1c5b2abe0SLewanczyk, Dawid /* 2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation 3c5b2abe0SLewanczyk, Dawid // 4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License"); 5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License. 6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at 7c5b2abe0SLewanczyk, Dawid // 8c5b2abe0SLewanczyk, Dawid // http://www.apache.org/licenses/LICENSE-2.0 9c5b2abe0SLewanczyk, Dawid // 10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software 11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS, 12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and 14c5b2abe0SLewanczyk, Dawid // limitations under the License. 15c5b2abe0SLewanczyk, Dawid */ 16c5b2abe0SLewanczyk, Dawid #pragma once 17c5b2abe0SLewanczyk, Dawid 1813451e39SWilly Tu #include "bmcweb_config.h" 1913451e39SWilly Tu 203ccb3adbSEd Tanous #include "app.hpp" 211e1e598dSJonathan Doman #include "dbus_singleton.hpp" 227a1dbc48SGeorge Liu #include "dbus_utility.hpp" 23539d8c6bSEd Tanous #include "generated/enums/action_info.hpp" 248d69c668SEd Tanous #include "generated/enums/computer_system.hpp" 25539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp" 2633e1f122SAndrew Geissler #include "generated/enums/resource.hpp" 27746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 281c8fba97SJames Feist #include "led.hpp" 29f4c99e70SEd Tanous #include "query.hpp" 30c5d03ff4SJennifer Lee #include "redfish_util.hpp" 313ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 323ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 333ccb3adbSEd Tanous #include "utils/json_utils.hpp" 34472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 353ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 362b82937eSEd Tanous #include "utils/time_utils.hpp" 37c5d03ff4SJennifer Lee 38fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 399712f8acSEd Tanous #include <boost/container/flat_map.hpp> 40e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 4133e1f122SAndrew Geissler #include <boost/system/linux_error.hpp> 42ef4c65b7SEd Tanous #include <boost/url/format.hpp> 431e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 44fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 45bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 461214b7e7SGunnar Mills 477a1dbc48SGeorge Liu #include <array> 4833e1f122SAndrew Geissler #include <memory> 496b9ac4f2SChris Cain #include <string> 507a1dbc48SGeorge Liu #include <string_view> 5120fa6a2cSEd Tanous #include <utility> 52abf2add6SEd Tanous #include <variant> 536b9ac4f2SChris Cain #include <vector> 54c5b2abe0SLewanczyk, Dawid 551abe55efSEd Tanous namespace redfish 561abe55efSEd Tanous { 57c5b2abe0SLewanczyk, Dawid 585c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 595c3e9272SAbhishek Patel protocolToDBusForSystems{ 605c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 615c3e9272SAbhishek Patel 629d3ae10eSAlpana Kumari /** 639d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 649d3ae10eSAlpana Kumari * 65ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 669d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 679d3ae10eSAlpana Kumari * 689d3ae10eSAlpana Kumari * @return None. 699d3ae10eSAlpana Kumari */ 70bd79bce8SPatrick Williams inline void updateDimmProperties( 71bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional) 729d3ae10eSAlpana Kumari { 7362598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 749d3ae10eSAlpana Kumari 759d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 769d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 779d3ae10eSAlpana Kumari // ENABLED. 7802cad96eSEd Tanous const nlohmann::json& prevMemSummary = 79ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 809d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 819d3ae10eSAlpana Kumari { 82e05aec50SEd Tanous if (isDimmFunctional) 839d3ae10eSAlpana Kumari { 84ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 859d3ae10eSAlpana Kumari "Enabled"; 869d3ae10eSAlpana Kumari } 879d3ae10eSAlpana Kumari } 889d3ae10eSAlpana Kumari } 899d3ae10eSAlpana Kumari 9057e8c9beSAlpana Kumari /* 9157e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 9257e8c9beSAlpana Kumari * CPU Functional State 9357e8c9beSAlpana Kumari * 94ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 9557e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9657e8c9beSAlpana Kumari * 9757e8c9beSAlpana Kumari * @return None. 9857e8c9beSAlpana Kumari */ 99ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 100ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 10157e8c9beSAlpana Kumari { 10262598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 10357e8c9beSAlpana Kumari 10402cad96eSEd Tanous const nlohmann::json& prevProcState = 105ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10657e8c9beSAlpana Kumari 10757e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10857e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10957e8c9beSAlpana Kumari // Functional. 11057e8c9beSAlpana Kumari if (prevProcState == "Disabled") 11157e8c9beSAlpana Kumari { 112e05aec50SEd Tanous if (isCpuFunctional) 11357e8c9beSAlpana Kumari { 114ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 11557e8c9beSAlpana Kumari "Enabled"; 11657e8c9beSAlpana Kumari } 11757e8c9beSAlpana Kumari } 11857e8c9beSAlpana Kumari } 11957e8c9beSAlpana Kumari 120cf0e004cSNinad Palsule /* 121cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 122cf0e004cSNinad Palsule * 123ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 124cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 125cf0e004cSNinad Palsule * 126cf0e004cSNinad Palsule * @return None. 127cf0e004cSNinad Palsule */ 128bd79bce8SPatrick Williams inline void modifyCpuPresenceState( 129bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent) 130cf0e004cSNinad Palsule { 13162598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 132cf0e004cSNinad Palsule 133cf0e004cSNinad Palsule if (isCpuPresent) 134cf0e004cSNinad Palsule { 135cf0e004cSNinad Palsule nlohmann::json& procCount = 136ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 137cf0e004cSNinad Palsule auto* procCountPtr = 138cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 139cf0e004cSNinad Palsule if (procCountPtr != nullptr) 140cf0e004cSNinad Palsule { 141cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 142cf0e004cSNinad Palsule *procCountPtr += 1; 143cf0e004cSNinad Palsule } 144cf0e004cSNinad Palsule } 145cf0e004cSNinad Palsule } 146cf0e004cSNinad Palsule 147382d6475SAli Ahmed inline void getProcessorProperties( 148ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 149382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 150382d6475SAli Ahmed properties) 15103fbed92SAli Ahmed { 15262598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 15303fbed92SAli Ahmed 15403fbed92SAli Ahmed // TODO: Get Model 15503fbed92SAli Ahmed 156bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15703fbed92SAli Ahmed 158bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 159bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 16003fbed92SAli Ahmed 161bc1d29deSKrzysztof Grobelny if (!success) 16203fbed92SAli Ahmed { 163ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16403fbed92SAli Ahmed return; 16503fbed92SAli Ahmed } 16603fbed92SAli Ahmed 167bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16803fbed92SAli Ahmed { 169bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 170ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 171bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 172bc1d29deSKrzysztof Grobelny 173bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 174bc1d29deSKrzysztof Grobelny { 175bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17603fbed92SAli Ahmed } 17703fbed92SAli Ahmed else 17803fbed92SAli Ahmed { 179bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 18003fbed92SAli Ahmed } 18103fbed92SAli Ahmed } 18203fbed92SAli Ahmed } 18303fbed92SAli Ahmed 18403fbed92SAli Ahmed /* 18503fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18603fbed92SAli Ahmed * 187ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 18803fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 18903fbed92SAli Ahmed * @param[in] path dbus path for Cpu 19003fbed92SAli Ahmed * 19103fbed92SAli Ahmed * @return None. 19203fbed92SAli Ahmed */ 193ac106bf6SEd Tanous inline void 194ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 195ac106bf6SEd Tanous const std::string& service, const std::string& path) 19603fbed92SAli Ahmed { 197ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 198382d6475SAli Ahmed const bool cpuPresenceCheck) { 199382d6475SAli Ahmed if (ec3) 200382d6475SAli Ahmed { 20162598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 202382d6475SAli Ahmed return; 203382d6475SAli Ahmed } 204ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 205382d6475SAli Ahmed }; 206382d6475SAli Ahmed 207cf0e004cSNinad Palsule // Get the Presence of CPU 208cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 209cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 210cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 211cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 212cf0e004cSNinad Palsule 213bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 214bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 215bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 216ac106bf6SEd Tanous [asyncResp, service, 2175e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 218b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 21903fbed92SAli Ahmed if (ec2) 22003fbed92SAli Ahmed { 22162598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 222ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22303fbed92SAli Ahmed return; 22403fbed92SAli Ahmed } 225ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 226bc1d29deSKrzysztof Grobelny }); 22703fbed92SAli Ahmed } 22803fbed92SAli Ahmed 22957e8c9beSAlpana Kumari /* 230cf0e004cSNinad Palsule * @brief processMemoryProperties fields 231cf0e004cSNinad Palsule * 232ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 233cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 234cf0e004cSNinad Palsule * 235cf0e004cSNinad Palsule * @return None. 236cf0e004cSNinad Palsule */ 237cf0e004cSNinad Palsule inline void 238ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 239cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 240cf0e004cSNinad Palsule { 24162598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 242cf0e004cSNinad Palsule 243cf0e004cSNinad Palsule if (properties.empty()) 244cf0e004cSNinad Palsule { 245cf0e004cSNinad Palsule return; 246cf0e004cSNinad Palsule } 247cf0e004cSNinad Palsule 248cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 249cf0e004cSNinad Palsule 250cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 251cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 252cf0e004cSNinad Palsule memorySizeInKB); 253cf0e004cSNinad Palsule 254cf0e004cSNinad Palsule if (!success) 255cf0e004cSNinad Palsule { 256ac106bf6SEd Tanous messages::internalError(asyncResp->res); 257cf0e004cSNinad Palsule return; 258cf0e004cSNinad Palsule } 259cf0e004cSNinad Palsule 260cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 261cf0e004cSNinad Palsule { 262cf0e004cSNinad Palsule nlohmann::json& totalMemory = 263ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 264dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 265cf0e004cSNinad Palsule if (preValue == nullptr) 266cf0e004cSNinad Palsule { 267ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 268dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 269cf0e004cSNinad Palsule } 270cf0e004cSNinad Palsule else 271cf0e004cSNinad Palsule { 272ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 273dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 274dfb2b408SPriyanga Ramasamy *preValue; 275cf0e004cSNinad Palsule } 276cf0e004cSNinad Palsule } 277cf0e004cSNinad Palsule } 278cf0e004cSNinad Palsule 279cf0e004cSNinad Palsule /* 280cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 281cf0e004cSNinad Palsule * 282ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 283cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 284cf0e004cSNinad Palsule * @param[in] path dbus path for memory 285cf0e004cSNinad Palsule * 286cf0e004cSNinad Palsule * @return None. 287cf0e004cSNinad Palsule */ 288ac106bf6SEd Tanous inline void 289ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 290ac106bf6SEd Tanous const std::string& service, const std::string& path) 291cf0e004cSNinad Palsule { 292cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 293cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 294cf0e004cSNinad Palsule "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 346a974c132SLakshmi Yadlapati inline void 347a974c132SLakshmi Yadlapati afterGetInventory(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 469bc1d29deSKrzysztof Grobelny sdbusplus::asio::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 { 481bc1d29deSKrzysztof Grobelny sdbusplus::asio::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 4901e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 491a974c132SLakshmi Yadlapati *crow::connections::systemBus, 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 */ 509a974c132SLakshmi Yadlapati inline void 51051bd2d8aSGunnar Mills getComputerSystem(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."); 5351e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5361e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 5371e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 5381e1e598dSJonathan Doman "CurrentHostState", 539ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 5401e1e598dSJonathan Doman const std::string& hostState) { 5411abe55efSEd Tanous if (ec) 5421abe55efSEd Tanous { 54322228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 54422228c28SAndrew Geissler { 54522228c28SAndrew Geissler // Service not available, no error, just don't return 54622228c28SAndrew Geissler // host state info 54762598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 54822228c28SAndrew Geissler return; 54922228c28SAndrew Geissler } 55062598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 551ac106bf6SEd Tanous messages::internalError(asyncResp->res); 552c5b2abe0SLewanczyk, Dawid return; 553c5b2abe0SLewanczyk, Dawid } 5546617338dSEd Tanous 55562598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 556c5b2abe0SLewanczyk, Dawid // Verify Host State 5571e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5581abe55efSEd Tanous { 559bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 560bd79bce8SPatrick Williams resource::PowerState::On; 561539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 562539d8c6bSEd Tanous resource::State::Enabled; 5631abe55efSEd Tanous } 5641e1e598dSJonathan Doman else if (hostState == 5650fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5668c888608SGunnar Mills { 567bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 568bd79bce8SPatrick Williams resource::PowerState::On; 569539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 570539d8c6bSEd Tanous resource::State::Quiesced; 5718c888608SGunnar Mills } 5721e1e598dSJonathan Doman else if (hostState == 5730fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 57483935af9SAndrew Geissler { 575bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 576bd79bce8SPatrick Williams resource::PowerState::On; 577539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 578539d8c6bSEd Tanous resource::State::InTest; 57983935af9SAndrew Geissler } 5800fda0f12SGeorge Liu else if ( 5811e1e598dSJonathan Doman hostState == 5820fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5831a2a1437SAndrew Geissler { 584539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 585539d8c6bSEd Tanous resource::PowerState::PoweringOn; 586539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 587539d8c6bSEd Tanous resource::State::Starting; 5881a2a1437SAndrew Geissler } 589bd79bce8SPatrick Williams else if ( 590bd79bce8SPatrick Williams hostState == 5910fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5921a2a1437SAndrew Geissler { 593539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 594539d8c6bSEd Tanous resource::PowerState::PoweringOff; 595539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 596539d8c6bSEd Tanous resource::State::Disabled; 5971a2a1437SAndrew Geissler } 5981abe55efSEd Tanous else 5991abe55efSEd Tanous { 600bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 601bd79bce8SPatrick Williams resource::PowerState::Off; 602539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 603539d8c6bSEd Tanous resource::State::Disabled; 604c5b2abe0SLewanczyk, Dawid } 6051e1e598dSJonathan Doman }); 606c5b2abe0SLewanczyk, Dawid } 607c5b2abe0SLewanczyk, Dawid 608c5b2abe0SLewanczyk, Dawid /** 609786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 610491d8ee7SSantosh Puranik * 611491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 612491d8ee7SSantosh Puranik * 613491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 614491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 615491d8ee7SSantosh Puranik */ 61623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 617491d8ee7SSantosh Puranik { 618491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 619491d8ee7SSantosh Puranik { 620491d8ee7SSantosh Puranik return "None"; 621491d8ee7SSantosh Puranik } 6223174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 623491d8ee7SSantosh Puranik { 624491d8ee7SSantosh Puranik return "Hdd"; 625491d8ee7SSantosh Puranik } 6263174e4dfSEd Tanous if (dbusSource == 627a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 628491d8ee7SSantosh Puranik { 629491d8ee7SSantosh Puranik return "Cd"; 630491d8ee7SSantosh Puranik } 6313174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 632491d8ee7SSantosh Puranik { 633491d8ee7SSantosh Puranik return "Pxe"; 634491d8ee7SSantosh Puranik } 6353174e4dfSEd Tanous if (dbusSource == 636944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6379f16b2c1SJennifer Lee { 6389f16b2c1SJennifer Lee return "Usb"; 6399f16b2c1SJennifer Lee } 640491d8ee7SSantosh Puranik return ""; 641491d8ee7SSantosh Puranik } 642491d8ee7SSantosh Puranik 643491d8ee7SSantosh Puranik /** 644cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 645cd9a4666SKonstantin Aladyshev * 646cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 647cd9a4666SKonstantin Aladyshev * 648cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 649cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 650cd9a4666SKonstantin Aladyshev */ 651cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 652cd9a4666SKonstantin Aladyshev { 653cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 654cd9a4666SKonstantin Aladyshev { 655cd9a4666SKonstantin Aladyshev return "Legacy"; 656cd9a4666SKonstantin Aladyshev } 657cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 658cd9a4666SKonstantin Aladyshev { 659cd9a4666SKonstantin Aladyshev return "UEFI"; 660cd9a4666SKonstantin Aladyshev } 661cd9a4666SKonstantin Aladyshev return ""; 662cd9a4666SKonstantin Aladyshev } 663cd9a4666SKonstantin Aladyshev 664cd9a4666SKonstantin Aladyshev /** 665786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 666491d8ee7SSantosh Puranik * 667491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 668491d8ee7SSantosh Puranik * 669491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 670491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 671491d8ee7SSantosh Puranik */ 67223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 673491d8ee7SSantosh Puranik { 674491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 675491d8ee7SSantosh Puranik { 676491d8ee7SSantosh Puranik return "None"; 677491d8ee7SSantosh Puranik } 6783174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 679491d8ee7SSantosh Puranik { 680491d8ee7SSantosh Puranik return "Diags"; 681491d8ee7SSantosh Puranik } 6823174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 683491d8ee7SSantosh Puranik { 684491d8ee7SSantosh Puranik return "BiosSetup"; 685491d8ee7SSantosh Puranik } 686491d8ee7SSantosh Puranik return ""; 687491d8ee7SSantosh Puranik } 688491d8ee7SSantosh Puranik 689491d8ee7SSantosh Puranik /** 690e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 691e43914b3SAndrew Geissler * 692e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 693e43914b3SAndrew Geissler * 694e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 695e43914b3SAndrew Geissler * translation cannot be done, returns "None". 696e43914b3SAndrew Geissler */ 697e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 698e43914b3SAndrew Geissler { 699e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 700e43914b3SAndrew Geissler // enum 701e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 702e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 703e43914b3SAndrew Geissler "ProgressStages.Unspecified") 704e43914b3SAndrew Geissler { 705e43914b3SAndrew Geissler rfBpLastState = "None"; 706e43914b3SAndrew Geissler } 707e43914b3SAndrew Geissler else if (dbusBootProgress == 708e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 709e43914b3SAndrew Geissler "PrimaryProcInit") 710e43914b3SAndrew Geissler { 711e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 712e43914b3SAndrew Geissler } 713e43914b3SAndrew Geissler else if (dbusBootProgress == 714e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 715e43914b3SAndrew Geissler "BusInit") 716e43914b3SAndrew Geissler { 717e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 718e43914b3SAndrew Geissler } 719e43914b3SAndrew Geissler else if (dbusBootProgress == 720e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 721e43914b3SAndrew Geissler "MemoryInit") 722e43914b3SAndrew Geissler { 723e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 724e43914b3SAndrew Geissler } 725e43914b3SAndrew Geissler else if (dbusBootProgress == 726e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 727e43914b3SAndrew Geissler "SecondaryProcInit") 728e43914b3SAndrew Geissler { 729e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 730e43914b3SAndrew Geissler } 731e43914b3SAndrew Geissler else if (dbusBootProgress == 732e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 733e43914b3SAndrew Geissler "PCIInit") 734e43914b3SAndrew Geissler { 735e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 736e43914b3SAndrew Geissler } 737e43914b3SAndrew Geissler else if (dbusBootProgress == 738e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 739e43914b3SAndrew Geissler "SystemSetup") 740e43914b3SAndrew Geissler { 741e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 742e43914b3SAndrew Geissler } 743e43914b3SAndrew Geissler else if (dbusBootProgress == 744e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 745e43914b3SAndrew Geissler "SystemInitComplete") 746e43914b3SAndrew Geissler { 747e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 748e43914b3SAndrew Geissler } 749e43914b3SAndrew Geissler else if (dbusBootProgress == 750e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 751e43914b3SAndrew Geissler "OSStart") 752e43914b3SAndrew Geissler { 753e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 754e43914b3SAndrew Geissler } 755e43914b3SAndrew Geissler else if (dbusBootProgress == 756e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 757e43914b3SAndrew Geissler "OSRunning") 758e43914b3SAndrew Geissler { 759e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 760e43914b3SAndrew Geissler } 761e43914b3SAndrew Geissler else 762e43914b3SAndrew Geissler { 76362598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 764e43914b3SAndrew Geissler // Just return the default 765e43914b3SAndrew Geissler } 766e43914b3SAndrew Geissler return rfBpLastState; 767e43914b3SAndrew Geissler } 768e43914b3SAndrew Geissler 769e43914b3SAndrew Geissler /** 770786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 771491d8ee7SSantosh Puranik * 772491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 773944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 774944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 775491d8ee7SSantosh Puranik * 776944ffaf9SJohnathan Mantey * @return Integer error code. 777491d8ee7SSantosh Puranik */ 778bd79bce8SPatrick Williams inline int assignBootParameters( 779bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 780bd79bce8SPatrick Williams const std::string& rfSource, std::string& bootSource, std::string& bootMode) 781491d8ee7SSantosh Puranik { 782c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 783c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 784944ffaf9SJohnathan Mantey 785491d8ee7SSantosh Puranik if (rfSource == "None") 786491d8ee7SSantosh Puranik { 787944ffaf9SJohnathan Mantey return 0; 788491d8ee7SSantosh Puranik } 7893174e4dfSEd Tanous if (rfSource == "Pxe") 790491d8ee7SSantosh Puranik { 791944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 792944ffaf9SJohnathan Mantey } 793944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 794944ffaf9SJohnathan Mantey { 795944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 796944ffaf9SJohnathan Mantey } 797944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 798944ffaf9SJohnathan Mantey { 799944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 800944ffaf9SJohnathan Mantey } 801944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 802944ffaf9SJohnathan Mantey { 803944ffaf9SJohnathan Mantey bootSource = 804944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 805944ffaf9SJohnathan Mantey } 806944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 807944ffaf9SJohnathan Mantey { 808944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 809491d8ee7SSantosh Puranik } 8109f16b2c1SJennifer Lee else if (rfSource == "Usb") 8119f16b2c1SJennifer Lee { 812944ffaf9SJohnathan Mantey bootSource = 813944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8149f16b2c1SJennifer Lee } 815491d8ee7SSantosh Puranik else 816491d8ee7SSantosh Puranik { 81762598e31SEd Tanous BMCWEB_LOG_DEBUG( 81862598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 81962598e31SEd Tanous bootSource); 820ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 821944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 822944ffaf9SJohnathan Mantey return -1; 823491d8ee7SSantosh Puranik } 824944ffaf9SJohnathan Mantey return 0; 825491d8ee7SSantosh Puranik } 8261981771bSAli Ahmed 827978b8803SAndrew Geissler /** 828978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 829978b8803SAndrew Geissler * 830ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 831978b8803SAndrew Geissler * 832978b8803SAndrew Geissler * @return None. 833978b8803SAndrew Geissler */ 834ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 835978b8803SAndrew Geissler { 8361e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8371e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8381e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8391e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 840ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8411e1e598dSJonathan Doman const std::string& bootProgressStr) { 842978b8803SAndrew Geissler if (ec) 843978b8803SAndrew Geissler { 844978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 845978b8803SAndrew Geissler // not found 846978b8803SAndrew Geissler return; 847978b8803SAndrew Geissler } 848978b8803SAndrew Geissler 84962598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 850978b8803SAndrew Geissler 851ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 852e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8531e1e598dSJonathan Doman }); 854978b8803SAndrew Geissler } 855491d8ee7SSantosh Puranik 856491d8ee7SSantosh Puranik /** 857b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 858b6d5d45cSHieu Huynh * 859ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 860b6d5d45cSHieu Huynh * 861b6d5d45cSHieu Huynh * @return None. 862b6d5d45cSHieu Huynh */ 863b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 864ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 865b6d5d45cSHieu Huynh { 866b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 867b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 868b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 869b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 870ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 871b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 872b6d5d45cSHieu Huynh if (ec) 873b6d5d45cSHieu Huynh { 87462598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 875b6d5d45cSHieu Huynh return; 876b6d5d45cSHieu Huynh } 877b6d5d45cSHieu Huynh 878b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 879b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 880b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 881b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 882b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 883b6d5d45cSHieu Huynh 884b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 885ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 886b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 887b6d5d45cSHieu Huynh }); 888b6d5d45cSHieu Huynh } 889b6d5d45cSHieu Huynh 890b6d5d45cSHieu Huynh /** 891c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 892cd9a4666SKonstantin Aladyshev * 893ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 894cd9a4666SKonstantin Aladyshev * 895cd9a4666SKonstantin Aladyshev * @return None. 896cd9a4666SKonstantin Aladyshev */ 897cd9a4666SKonstantin Aladyshev 898ac106bf6SEd Tanous inline void 899ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 900cd9a4666SKonstantin Aladyshev { 9011e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9021e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9031e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9041e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 905ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9061e1e598dSJonathan Doman const std::string& bootType) { 907cd9a4666SKonstantin Aladyshev if (ec) 908cd9a4666SKonstantin Aladyshev { 909cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 910cd9a4666SKonstantin Aladyshev return; 911cd9a4666SKonstantin Aladyshev } 912cd9a4666SKonstantin Aladyshev 91362598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 914cd9a4666SKonstantin Aladyshev 915ac106bf6SEd Tanous asyncResp->res 916ac106bf6SEd Tanous .jsonValue["Boot"] 917002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 918613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 919cd9a4666SKonstantin Aladyshev 9201e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 921cd9a4666SKonstantin Aladyshev if (rfType.empty()) 922cd9a4666SKonstantin Aladyshev { 923ac106bf6SEd Tanous messages::internalError(asyncResp->res); 924cd9a4666SKonstantin Aladyshev return; 925cd9a4666SKonstantin Aladyshev } 926cd9a4666SKonstantin Aladyshev 927ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9281e1e598dSJonathan Doman }); 929cd9a4666SKonstantin Aladyshev } 930cd9a4666SKonstantin Aladyshev 931cd9a4666SKonstantin Aladyshev /** 932c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 933491d8ee7SSantosh Puranik * 934ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 935491d8ee7SSantosh Puranik * 936491d8ee7SSantosh Puranik * @return None. 937491d8ee7SSantosh Puranik */ 938c21865c4SKonstantin Aladyshev 939ac106bf6SEd Tanous inline void 940ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 941491d8ee7SSantosh Puranik { 9421e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9431e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9441e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9451e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 946ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9471e1e598dSJonathan Doman const std::string& bootModeStr) { 948491d8ee7SSantosh Puranik if (ec) 949491d8ee7SSantosh Puranik { 950b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 951ac106bf6SEd Tanous messages::internalError(asyncResp->res); 952491d8ee7SSantosh Puranik return; 953491d8ee7SSantosh Puranik } 954491d8ee7SSantosh Puranik 95562598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 956491d8ee7SSantosh Puranik 95720fa6a2cSEd Tanous nlohmann::json::array_t allowed; 95820fa6a2cSEd Tanous allowed.emplace_back("None"); 95920fa6a2cSEd Tanous allowed.emplace_back("Pxe"); 96020fa6a2cSEd Tanous allowed.emplace_back("Hdd"); 96120fa6a2cSEd Tanous allowed.emplace_back("Cd"); 96220fa6a2cSEd Tanous allowed.emplace_back("Diags"); 96320fa6a2cSEd Tanous allowed.emplace_back("BiosSetup"); 96420fa6a2cSEd Tanous allowed.emplace_back("Usb"); 96520fa6a2cSEd Tanous 966ac106bf6SEd Tanous asyncResp->res 9670fda0f12SGeorge Liu .jsonValue["Boot"] 96820fa6a2cSEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = 96920fa6a2cSEd Tanous std::move(allowed); 9701e1e598dSJonathan Doman if (bootModeStr != 971491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 972491d8ee7SSantosh Puranik { 9731e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 974491d8ee7SSantosh Puranik if (!rfMode.empty()) 975491d8ee7SSantosh Puranik { 976bd79bce8SPatrick Williams asyncResp->res 977bd79bce8SPatrick Williams .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode; 978491d8ee7SSantosh Puranik } 979491d8ee7SSantosh Puranik } 9801e1e598dSJonathan Doman }); 981491d8ee7SSantosh Puranik } 982491d8ee7SSantosh Puranik 983491d8ee7SSantosh Puranik /** 984c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 985491d8ee7SSantosh Puranik * 986ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 987491d8ee7SSantosh Puranik * 988491d8ee7SSantosh Puranik * @return None. 989491d8ee7SSantosh Puranik */ 990c21865c4SKonstantin Aladyshev 991c21865c4SKonstantin Aladyshev inline void 992ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 993491d8ee7SSantosh Puranik { 9941e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9951e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9961e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9971e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 998ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9991e1e598dSJonathan Doman const std::string& bootSourceStr) { 1000491d8ee7SSantosh Puranik if (ec) 1001491d8ee7SSantosh Puranik { 10025ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10035ef735c8SNan Zhou { 10045ef735c8SNan Zhou return; 10055ef735c8SNan Zhou } 1006b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1007ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1008491d8ee7SSantosh Puranik return; 1009491d8ee7SSantosh Puranik } 1010491d8ee7SSantosh Puranik 101162598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 1012491d8ee7SSantosh Puranik 10131e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1014491d8ee7SSantosh Puranik if (!rfSource.empty()) 1015491d8ee7SSantosh Puranik { 1016ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1017ac106bf6SEd Tanous rfSource; 1018491d8ee7SSantosh Puranik } 1019cd9a4666SKonstantin Aladyshev 1020cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1021cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1022ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10231e1e598dSJonathan Doman }); 1024491d8ee7SSantosh Puranik } 1025491d8ee7SSantosh Puranik 1026491d8ee7SSantosh Puranik /** 1027c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1028c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1029c21865c4SKonstantin Aladyshev * state 1030491d8ee7SSantosh Puranik * 1031ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1032491d8ee7SSantosh Puranik * 1033491d8ee7SSantosh Puranik * @return None. 1034491d8ee7SSantosh Puranik */ 1035491d8ee7SSantosh Puranik 1036ac106bf6SEd Tanous inline void processBootOverrideEnable( 1037ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1038c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1039c21865c4SKonstantin Aladyshev { 1040c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1041c21865c4SKonstantin Aladyshev { 1042ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1043ac106bf6SEd Tanous "Disabled"; 1044c21865c4SKonstantin Aladyshev return; 1045c21865c4SKonstantin Aladyshev } 1046c21865c4SKonstantin Aladyshev 1047c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1048c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10491e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10501e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10511e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10521e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1053ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1054491d8ee7SSantosh Puranik if (ec) 1055491d8ee7SSantosh Puranik { 1056b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1057ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1058491d8ee7SSantosh Puranik return; 1059491d8ee7SSantosh Puranik } 1060491d8ee7SSantosh Puranik 1061c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1062c21865c4SKonstantin Aladyshev { 1063ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1064ac106bf6SEd Tanous "Once"; 1065c21865c4SKonstantin Aladyshev } 1066c21865c4SKonstantin Aladyshev else 1067c21865c4SKonstantin Aladyshev { 1068ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1069c21865c4SKonstantin Aladyshev "Continuous"; 1070c21865c4SKonstantin Aladyshev } 10711e1e598dSJonathan Doman }); 1072491d8ee7SSantosh Puranik } 1073491d8ee7SSantosh Puranik 1074491d8ee7SSantosh Puranik /** 1075c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1076c21865c4SKonstantin Aladyshev * 1077ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1078c21865c4SKonstantin Aladyshev * 1079c21865c4SKonstantin Aladyshev * @return None. 1080c21865c4SKonstantin Aladyshev */ 1081c21865c4SKonstantin Aladyshev 1082c21865c4SKonstantin Aladyshev inline void 1083ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1084c21865c4SKonstantin Aladyshev { 10851e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10861e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10871e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10881e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1089ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10901e1e598dSJonathan Doman const bool bootOverrideEnable) { 1091c21865c4SKonstantin Aladyshev if (ec) 1092c21865c4SKonstantin Aladyshev { 10935ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10945ef735c8SNan Zhou { 10955ef735c8SNan Zhou return; 10965ef735c8SNan Zhou } 1097b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1098ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1099c21865c4SKonstantin Aladyshev return; 1100c21865c4SKonstantin Aladyshev } 1101c21865c4SKonstantin Aladyshev 1102ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11031e1e598dSJonathan Doman }); 1104c21865c4SKonstantin Aladyshev } 1105c21865c4SKonstantin Aladyshev 1106c21865c4SKonstantin Aladyshev /** 1107c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1108c21865c4SKonstantin Aladyshev * 1109ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1110c21865c4SKonstantin Aladyshev * 1111c21865c4SKonstantin Aladyshev * @return None. 1112c21865c4SKonstantin Aladyshev */ 1113ac106bf6SEd Tanous inline void 1114ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1115c21865c4SKonstantin Aladyshev { 111662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1117c21865c4SKonstantin Aladyshev 1118ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1119ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1120ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1121c21865c4SKonstantin Aladyshev } 1122c21865c4SKonstantin Aladyshev 1123c21865c4SKonstantin Aladyshev /** 1124c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1125c0557e1aSGunnar Mills * 1126c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1127c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1128c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1129c0557e1aSGunnar Mills * last power operation time. 1130c0557e1aSGunnar Mills * 1131ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1132c0557e1aSGunnar Mills * 1133c0557e1aSGunnar Mills * @return None. 1134c0557e1aSGunnar Mills */ 1135ac106bf6SEd Tanous inline void 1136ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1137c0557e1aSGunnar Mills { 113862598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1139c0557e1aSGunnar Mills 11401e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11411e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11421e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11431e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1144ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1145ac106bf6SEd Tanous uint64_t lastResetTime) { 1146c0557e1aSGunnar Mills if (ec) 1147c0557e1aSGunnar Mills { 114862598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1149c0557e1aSGunnar Mills return; 1150c0557e1aSGunnar Mills } 1151c0557e1aSGunnar Mills 1152c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1153c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11541e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1155c0557e1aSGunnar Mills 1156c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1157ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 11582b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11591e1e598dSJonathan Doman }); 1160c0557e1aSGunnar Mills } 1161c0557e1aSGunnar Mills 1162c0557e1aSGunnar Mills /** 1163797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1164797d5daeSCorey Hardesty * 1165797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1166797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1167797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1168797d5daeSCorey Hardesty * dbus. 1169797d5daeSCorey Hardesty * 1170ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1171797d5daeSCorey Hardesty * 1172797d5daeSCorey Hardesty * @return None. 1173797d5daeSCorey Hardesty */ 1174ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1175ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1176797d5daeSCorey Hardesty { 117762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1178797d5daeSCorey Hardesty 1179797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1180797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1181797d5daeSCorey Hardesty "/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 { 1188797d5daeSCorey Hardesty if (ec.value() != EBADR) 1189797d5daeSCorey Hardesty { 119062598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1191ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1192797d5daeSCorey Hardesty } 1193797d5daeSCorey Hardesty return; 1194797d5daeSCorey Hardesty } 1195797d5daeSCorey Hardesty 1196797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1197797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1198797d5daeSCorey Hardesty 1199797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1200bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), propertiesList, 1201bd79bce8SPatrick Williams "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts); 1202797d5daeSCorey Hardesty 1203797d5daeSCorey Hardesty if (!success) 1204797d5daeSCorey Hardesty { 1205ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1206797d5daeSCorey Hardesty return; 1207797d5daeSCorey Hardesty } 1208797d5daeSCorey Hardesty 1209797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1210797d5daeSCorey Hardesty { 1211ac106bf6SEd Tanous asyncResp->res 1212ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1213797d5daeSCorey Hardesty *attemptsLeft; 1214797d5daeSCorey Hardesty } 1215797d5daeSCorey Hardesty 1216797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1217797d5daeSCorey Hardesty { 1218ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1219797d5daeSCorey Hardesty *retryAttempts; 1220797d5daeSCorey Hardesty } 1221797d5daeSCorey Hardesty }); 1222797d5daeSCorey Hardesty } 1223797d5daeSCorey Hardesty 1224797d5daeSCorey Hardesty /** 12256bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12266bd5a8d2SGunnar Mills * 1227ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12286bd5a8d2SGunnar Mills * 12296bd5a8d2SGunnar Mills * @return None. 12306bd5a8d2SGunnar Mills */ 1231797d5daeSCorey Hardesty inline void 1232ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12336bd5a8d2SGunnar Mills { 123462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12356bd5a8d2SGunnar Mills 12361e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12371e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12381e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12391e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1240ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1241ac106bf6SEd Tanous bool autoRebootEnabled) { 12426bd5a8d2SGunnar Mills if (ec) 12436bd5a8d2SGunnar Mills { 1244797d5daeSCorey Hardesty if (ec.value() != EBADR) 1245797d5daeSCorey Hardesty { 124662598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1247ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1248797d5daeSCorey Hardesty } 12496bd5a8d2SGunnar Mills return; 12506bd5a8d2SGunnar Mills } 12516bd5a8d2SGunnar Mills 125262598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1253e05aec50SEd Tanous if (autoRebootEnabled) 12546bd5a8d2SGunnar Mills { 1255ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12566bd5a8d2SGunnar Mills "RetryAttempts"; 12576bd5a8d2SGunnar Mills } 12586bd5a8d2SGunnar Mills else 12596bd5a8d2SGunnar Mills { 1260ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1261ac106bf6SEd Tanous "Disabled"; 12626bd5a8d2SGunnar Mills } 1263ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 126469f35306SGunnar Mills 126569f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 126669f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 126769f35306SGunnar Mills // RetryAttempts. 126820fa6a2cSEd Tanous nlohmann::json::array_t allowed; 126920fa6a2cSEd Tanous allowed.emplace_back("Disabled"); 127020fa6a2cSEd Tanous allowed.emplace_back("RetryAttempts"); 1271ac106bf6SEd Tanous asyncResp->res 1272bd79bce8SPatrick Williams .jsonValue["Boot"] 1273bd79bce8SPatrick Williams ["AutomaticRetryConfig@Redfish.AllowableValues"] = 127420fa6a2cSEd Tanous std::move(allowed); 12751e1e598dSJonathan Doman }); 12766bd5a8d2SGunnar Mills } 12776bd5a8d2SGunnar Mills 12786bd5a8d2SGunnar Mills /** 1279797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1280797d5daeSCorey Hardesty * 1281ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1282797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1283797d5daeSCorey Hardesty * 1284797d5daeSCorey Hardesty *@return None. 1285797d5daeSCorey Hardesty */ 1286797d5daeSCorey Hardesty 1287ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1288ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1289797d5daeSCorey Hardesty const uint32_t retryAttempts) 1290797d5daeSCorey Hardesty { 129162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 129287c44966SAsmitha Karunanithi setDbusProperty( 1293e93abac6SGinu George asyncResp, "Boot/AutomaticRetryAttempts", 1294e93abac6SGinu George "xyz.openbmc_project.State.Host", 129587c44966SAsmitha Karunanithi sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"), 12969ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1297e93abac6SGinu George retryAttempts); 1298797d5daeSCorey Hardesty } 1299797d5daeSCorey Hardesty 13008d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 13018d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 13028d69c668SEd Tanous { 13038d69c668SEd Tanous if (value == 13048d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 13058d69c668SEd Tanous { 13068d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 13078d69c668SEd Tanous } 13088d69c668SEd Tanous if (value == 13098d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 13108d69c668SEd Tanous { 13118d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13128d69c668SEd Tanous } 13138d69c668SEd Tanous if (value == 13143a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 13158d69c668SEd Tanous { 13168d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13178d69c668SEd Tanous } 13188d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13198d69c668SEd Tanous { 13208d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13218d69c668SEd Tanous } 13228d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13238d69c668SEd Tanous } 1324797d5daeSCorey Hardesty /** 1325c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1326c6a620f2SGeorge Liu * 1327ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1328c6a620f2SGeorge Liu * 1329c6a620f2SGeorge Liu * @return None. 1330c6a620f2SGeorge Liu */ 13318d1b46d7Szhanghch05 inline void 1332ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1333c6a620f2SGeorge Liu { 133462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1335c6a620f2SGeorge Liu 13361e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13371e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13381e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13391e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1340ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13415e7e2dc5SEd Tanous const std::string& policy) { 1342c6a620f2SGeorge Liu if (ec) 1343c6a620f2SGeorge Liu { 134462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1345c6a620f2SGeorge Liu return; 1346c6a620f2SGeorge Liu } 13478d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 13488d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 13498d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1350c6a620f2SGeorge Liu { 1351ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1352c6a620f2SGeorge Liu return; 1353c6a620f2SGeorge Liu } 1354c6a620f2SGeorge Liu 13558d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 13561e1e598dSJonathan Doman }); 1357c6a620f2SGeorge Liu } 1358c6a620f2SGeorge Liu 1359c6a620f2SGeorge Liu /** 13609dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 13619dcfe8c1SAlbert Zhang * 13629dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 13639dcfe8c1SAlbert Zhang * 13649dcfe8c1SAlbert Zhang * @return None. 13659dcfe8c1SAlbert Zhang */ 13669dcfe8c1SAlbert Zhang inline void 13679dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13689dcfe8c1SAlbert Zhang { 136962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 13709dcfe8c1SAlbert Zhang 13719dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 13729dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13739dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 13749dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 13759dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 13769dcfe8c1SAlbert Zhang if (ec) 13779dcfe8c1SAlbert Zhang { 13789dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 13799dcfe8c1SAlbert Zhang { 1380b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 13819dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 13829dcfe8c1SAlbert Zhang } 13839dcfe8c1SAlbert Zhang return; 13849dcfe8c1SAlbert Zhang } 13859dcfe8c1SAlbert Zhang 13869dcfe8c1SAlbert Zhang if (value) 13879dcfe8c1SAlbert Zhang { 1388539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1389539d8c6bSEd Tanous computer_system::StopBootOnFault::AnyFault; 13909dcfe8c1SAlbert Zhang } 13919dcfe8c1SAlbert Zhang else 13929dcfe8c1SAlbert Zhang { 1393539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1394539d8c6bSEd Tanous computer_system::StopBootOnFault::Never; 13959dcfe8c1SAlbert Zhang } 13969dcfe8c1SAlbert Zhang }); 13979dcfe8c1SAlbert Zhang } 13989dcfe8c1SAlbert Zhang 13999dcfe8c1SAlbert Zhang /** 14001981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 14011981771bSAli Ahmed * TPM is required for booting the host. 14021981771bSAli Ahmed * 1403ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14041981771bSAli Ahmed * 14051981771bSAli Ahmed * @return None. 14061981771bSAli Ahmed */ 14071981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1408ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14091981771bSAli Ahmed { 141062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1411e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1412e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1413e99073f5SGeorge Liu dbus::utility::getSubTree( 1414e99073f5SGeorge Liu "/", 0, interfaces, 1415ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1416b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14171981771bSAli Ahmed if (ec) 14181981771bSAli Ahmed { 1419bd79bce8SPatrick Williams BMCWEB_LOG_DEBUG( 1420bd79bce8SPatrick Williams "DBUS response error on TPM.Policy GetSubTree{}", ec); 14211981771bSAli Ahmed // This is an optional D-Bus object so just return if 14221981771bSAli Ahmed // error occurs 14231981771bSAli Ahmed return; 14241981771bSAli Ahmed } 142526f6976fSEd Tanous if (subtree.empty()) 14261981771bSAli Ahmed { 14271981771bSAli Ahmed // As noted above, this is an optional interface so just return 14281981771bSAli Ahmed // if there is no instance found 14291981771bSAli Ahmed return; 14301981771bSAli Ahmed } 14311981771bSAli Ahmed 14321981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14331981771bSAli Ahmed if (subtree.size() > 1) 14341981771bSAli Ahmed { 143562598e31SEd Tanous BMCWEB_LOG_DEBUG( 143662598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 143762598e31SEd Tanous subtree.size()); 14381981771bSAli Ahmed // Throw an internal Error and return 1439ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14401981771bSAli Ahmed return; 14411981771bSAli Ahmed } 14421981771bSAli Ahmed 14431981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14441981771bSAli Ahmed // field 14451981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14461981771bSAli Ahmed { 144762598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1448ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14491981771bSAli Ahmed return; 14501981771bSAli Ahmed } 14511981771bSAli Ahmed 14521981771bSAli Ahmed const std::string& path = subtree[0].first; 14531981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14541981771bSAli Ahmed 14551981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14561e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14571e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14581e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1459ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1460ac106bf6SEd Tanous bool tpmRequired) { 14618a592810SEd Tanous if (ec2) 14621981771bSAli Ahmed { 1463bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 1464bd79bce8SPatrick Williams "D-BUS response error on TPM.Policy Get{}", ec2); 1465ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14661981771bSAli Ahmed return; 14671981771bSAli Ahmed } 14681981771bSAli Ahmed 14691e1e598dSJonathan Doman if (tpmRequired) 14701981771bSAli Ahmed { 1471ac106bf6SEd Tanous asyncResp->res 1472ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14731981771bSAli Ahmed "Required"; 14741981771bSAli Ahmed } 14751981771bSAli Ahmed else 14761981771bSAli Ahmed { 1477ac106bf6SEd Tanous asyncResp->res 1478ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14791981771bSAli Ahmed "Disabled"; 14801981771bSAli Ahmed } 14811e1e598dSJonathan Doman }); 1482e99073f5SGeorge Liu }); 14831981771bSAli Ahmed } 14841981771bSAli Ahmed 14851981771bSAli Ahmed /** 14861c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14871c05dae3SAli Ahmed * TPM is required for booting the host. 14881c05dae3SAli Ahmed * 1489ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14901c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14911c05dae3SAli Ahmed * 14921c05dae3SAli Ahmed * @return None. 14931c05dae3SAli Ahmed */ 14941c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1495ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 14961c05dae3SAli Ahmed { 149762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1498e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1499e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1500e99073f5SGeorge Liu dbus::utility::getSubTree( 1501e99073f5SGeorge Liu "/", 0, interfaces, 1502ac106bf6SEd Tanous [asyncResp, 1503e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1504e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15051c05dae3SAli Ahmed if (ec) 15061c05dae3SAli Ahmed { 1507bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 1508bd79bce8SPatrick Williams "DBUS response error on TPM.Policy GetSubTree{}", ec); 1509ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15101c05dae3SAli Ahmed return; 15111c05dae3SAli Ahmed } 151226f6976fSEd Tanous if (subtree.empty()) 15131c05dae3SAli Ahmed { 1514bd79bce8SPatrick Williams messages::propertyValueNotInList(asyncResp->res, 1515bd79bce8SPatrick Williams "ComputerSystem", 15161c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15171c05dae3SAli Ahmed return; 15181c05dae3SAli Ahmed } 15191c05dae3SAli Ahmed 15201c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15211c05dae3SAli Ahmed if (subtree.size() > 1) 15221c05dae3SAli Ahmed { 152362598e31SEd Tanous BMCWEB_LOG_DEBUG( 152462598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 152562598e31SEd Tanous subtree.size()); 15261c05dae3SAli Ahmed // Throw an internal Error and return 1527ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15281c05dae3SAli Ahmed return; 15291c05dae3SAli Ahmed } 15301c05dae3SAli Ahmed 15311c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15321c05dae3SAli Ahmed // field 15331c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15341c05dae3SAli Ahmed { 153562598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1536ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15371c05dae3SAli Ahmed return; 15381c05dae3SAli Ahmed } 15391c05dae3SAli Ahmed 15401c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15411c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15421c05dae3SAli Ahmed 15431c05dae3SAli Ahmed if (serv.empty()) 15441c05dae3SAli Ahmed { 154562598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1546ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15471c05dae3SAli Ahmed return; 15481c05dae3SAli Ahmed } 15491c05dae3SAli Ahmed 15501c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 1551e93abac6SGinu George setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv, 1552e93abac6SGinu George path, "xyz.openbmc_project.Control.TPM.Policy", 1553e93abac6SGinu George "TPMEnable", tpmRequired); 1554e99073f5SGeorge Liu }); 15551c05dae3SAli Ahmed } 15561c05dae3SAli Ahmed 15571c05dae3SAli Ahmed /** 1558491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1559491d8ee7SSantosh Puranik * 1560ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1561cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1562cd9a4666SKonstantin Aladyshev * @return Integer error code. 1563cd9a4666SKonstantin Aladyshev */ 1564ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1565cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1566cd9a4666SKonstantin Aladyshev { 1567c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1568cd9a4666SKonstantin Aladyshev 1569c21865c4SKonstantin Aladyshev if (!bootType) 1570cd9a4666SKonstantin Aladyshev { 1571c21865c4SKonstantin Aladyshev return; 1572c21865c4SKonstantin Aladyshev } 1573c21865c4SKonstantin Aladyshev 1574cd9a4666SKonstantin Aladyshev // Source target specified 157562598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1576cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1577cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1578cd9a4666SKonstantin Aladyshev { 1579cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1580cd9a4666SKonstantin Aladyshev } 1581cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1582cd9a4666SKonstantin Aladyshev { 1583cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1584cd9a4666SKonstantin Aladyshev } 1585cd9a4666SKonstantin Aladyshev else 1586cd9a4666SKonstantin Aladyshev { 158762598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 158862598e31SEd Tanous "BootSourceOverrideMode: {}", 158962598e31SEd Tanous *bootType); 1590ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1591cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1592cd9a4666SKonstantin Aladyshev return; 1593cd9a4666SKonstantin Aladyshev } 1594cd9a4666SKonstantin Aladyshev 1595cd9a4666SKonstantin Aladyshev // Act on validated parameters 159662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1597cd9a4666SKonstantin Aladyshev 1598e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode", 1599e93abac6SGinu George "xyz.openbmc_project.Settings", 160087c44966SAsmitha Karunanithi sdbusplus::message::object_path( 160187c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 160287c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Type", "BootType", 1603e93abac6SGinu George bootTypeStr); 1604cd9a4666SKonstantin Aladyshev } 1605cd9a4666SKonstantin Aladyshev 1606cd9a4666SKonstantin Aladyshev /** 1607cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1608cd9a4666SKonstantin Aladyshev * 1609ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1610ac106bf6SEd Tanous * message. 1611c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1612c21865c4SKonstantin Aladyshev * @return Integer error code. 1613c21865c4SKonstantin Aladyshev */ 1614ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1615c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1616c21865c4SKonstantin Aladyshev { 1617c21865c4SKonstantin Aladyshev if (!bootEnable) 1618c21865c4SKonstantin Aladyshev { 1619c21865c4SKonstantin Aladyshev return; 1620c21865c4SKonstantin Aladyshev } 1621c21865c4SKonstantin Aladyshev // Source target specified 162262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1623c21865c4SKonstantin Aladyshev 1624c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1625c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1626c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1627c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1628c21865c4SKonstantin Aladyshev { 1629c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1630c21865c4SKonstantin Aladyshev } 1631c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1632c21865c4SKonstantin Aladyshev { 1633c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1634c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1635c21865c4SKonstantin Aladyshev } 1636c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1637c21865c4SKonstantin Aladyshev { 1638c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1639c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1640c21865c4SKonstantin Aladyshev } 1641c21865c4SKonstantin Aladyshev else 1642c21865c4SKonstantin Aladyshev { 164362598e31SEd Tanous BMCWEB_LOG_DEBUG( 164462598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 164562598e31SEd Tanous *bootEnable); 1646ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1647c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1648c21865c4SKonstantin Aladyshev return; 1649c21865c4SKonstantin Aladyshev } 1650c21865c4SKonstantin Aladyshev 1651c21865c4SKonstantin Aladyshev // Act on validated parameters 165262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1653c21865c4SKonstantin Aladyshev 1654e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1655e93abac6SGinu George "xyz.openbmc_project.Settings", 165687c44966SAsmitha Karunanithi sdbusplus::message::object_path( 165787c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 165887c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1659e93abac6SGinu George bootOverrideEnable); 1660c21865c4SKonstantin Aladyshev 1661c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1662c21865c4SKonstantin Aladyshev { 1663c21865c4SKonstantin Aladyshev return; 1664c21865c4SKonstantin Aladyshev } 1665c21865c4SKonstantin Aladyshev 1666c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1667c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 166862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 166962598e31SEd Tanous bootOverridePersistent); 1670c21865c4SKonstantin Aladyshev 1671e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1672e93abac6SGinu George "xyz.openbmc_project.Settings", 167387c44966SAsmitha Karunanithi sdbusplus::message::object_path( 167487c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot/one_time"), 167587c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1676e93abac6SGinu George !bootOverridePersistent); 1677c21865c4SKonstantin Aladyshev } 1678c21865c4SKonstantin Aladyshev 1679c21865c4SKonstantin Aladyshev /** 1680c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1681c21865c4SKonstantin Aladyshev * 1682ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1683491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1684491d8ee7SSantosh Puranik * 1685265c1602SJohnathan Mantey * @return Integer error code. 1686491d8ee7SSantosh Puranik */ 1687ac106bf6SEd Tanous inline void 1688ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1689cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1690491d8ee7SSantosh Puranik { 1691c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1692c21865c4SKonstantin Aladyshev std::string bootModeStr; 1693944ffaf9SJohnathan Mantey 1694c21865c4SKonstantin Aladyshev if (!bootSource) 1695491d8ee7SSantosh Puranik { 1696c21865c4SKonstantin Aladyshev return; 1697c21865c4SKonstantin Aladyshev } 1698c21865c4SKonstantin Aladyshev 1699491d8ee7SSantosh Puranik // Source target specified 170062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1701491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1702ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1703ac106bf6SEd Tanous bootModeStr) != 0) 1704491d8ee7SSantosh Puranik { 170562598e31SEd Tanous BMCWEB_LOG_DEBUG( 170662598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 170762598e31SEd Tanous *bootSource); 1708ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1709491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1710491d8ee7SSantosh Puranik return; 1711491d8ee7SSantosh Puranik } 1712491d8ee7SSantosh Puranik 1713944ffaf9SJohnathan Mantey // Act on validated parameters 171462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 171562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1716944ffaf9SJohnathan Mantey 1717e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1718e93abac6SGinu George "xyz.openbmc_project.Settings", 171987c44966SAsmitha Karunanithi sdbusplus::message::object_path( 172087c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 172187c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1722e93abac6SGinu George bootSourceStr); 1723e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1724e93abac6SGinu George "xyz.openbmc_project.Settings", 172587c44966SAsmitha Karunanithi sdbusplus::message::object_path( 172687c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 172787c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1728e93abac6SGinu George bootModeStr); 1729cd9a4666SKonstantin Aladyshev } 1730944ffaf9SJohnathan Mantey 1731cd9a4666SKonstantin Aladyshev /** 1732c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1733491d8ee7SSantosh Puranik * 1734ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1735491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1736cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1737491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1738491d8ee7SSantosh Puranik * 1739265c1602SJohnathan Mantey * @return Integer error code. 1740491d8ee7SSantosh Puranik */ 1741c21865c4SKonstantin Aladyshev 1742ac106bf6SEd Tanous inline void 1743ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1744c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1745c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1746c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1747491d8ee7SSantosh Puranik { 174862598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1749491d8ee7SSantosh Puranik 1750ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1751ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1752ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1753491d8ee7SSantosh Puranik } 1754491d8ee7SSantosh Puranik 1755c6a620f2SGeorge Liu /** 175698e386ecSGunnar Mills * @brief Sets AssetTag 175798e386ecSGunnar Mills * 1758ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 175998e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 176098e386ecSGunnar Mills * 176198e386ecSGunnar Mills * @return None. 176298e386ecSGunnar Mills */ 1763ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 176498e386ecSGunnar Mills const std::string& assetTag) 176598e386ecSGunnar Mills { 1766e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1767e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1768e99073f5SGeorge Liu dbus::utility::getSubTree( 1769e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1770ac106bf6SEd Tanous [asyncResp, 1771e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1772b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 177398e386ecSGunnar Mills if (ec) 177498e386ecSGunnar Mills { 177562598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1776ac106bf6SEd Tanous messages::internalError(asyncResp->res); 177798e386ecSGunnar Mills return; 177898e386ecSGunnar Mills } 177926f6976fSEd Tanous if (subtree.empty()) 178098e386ecSGunnar Mills { 178162598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1782ac106bf6SEd Tanous messages::internalError(asyncResp->res); 178398e386ecSGunnar Mills return; 178498e386ecSGunnar Mills } 178598e386ecSGunnar Mills // Assume only 1 system D-Bus object 178698e386ecSGunnar Mills // Throw an error if there is more than 1 178798e386ecSGunnar Mills if (subtree.size() > 1) 178898e386ecSGunnar Mills { 178962598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1790ac106bf6SEd Tanous messages::internalError(asyncResp->res); 179198e386ecSGunnar Mills return; 179298e386ecSGunnar Mills } 179398e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 179498e386ecSGunnar Mills { 179562598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1796ac106bf6SEd Tanous messages::internalError(asyncResp->res); 179798e386ecSGunnar Mills return; 179898e386ecSGunnar Mills } 179998e386ecSGunnar Mills 180098e386ecSGunnar Mills const std::string& path = subtree[0].first; 180198e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 180298e386ecSGunnar Mills 180398e386ecSGunnar Mills if (service.empty()) 180498e386ecSGunnar Mills { 180562598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1806ac106bf6SEd Tanous messages::internalError(asyncResp->res); 180798e386ecSGunnar Mills return; 180898e386ecSGunnar Mills } 180998e386ecSGunnar Mills 1810e93abac6SGinu George setDbusProperty(asyncResp, "AssetTag", service, path, 181187c44966SAsmitha Karunanithi "xyz.openbmc_project.Inventory.Decorator.AssetTag", 1812e93abac6SGinu George "AssetTag", assetTag); 1813e99073f5SGeorge Liu }); 181498e386ecSGunnar Mills } 181598e386ecSGunnar Mills 181698e386ecSGunnar Mills /** 18179dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 18189dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 18199dcfe8c1SAlbert Zhang * 18209dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 18219dcfe8c1SAlbert Zhang * stopBootOnFault 18229dcfe8c1SAlbert Zhang * 18239dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 18249dcfe8c1SAlbert Zhang */ 18259dcfe8c1SAlbert Zhang inline std::optional<bool> 18269dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 18279dcfe8c1SAlbert Zhang { 18289dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 18299dcfe8c1SAlbert Zhang { 18309dcfe8c1SAlbert Zhang return true; 18319dcfe8c1SAlbert Zhang } 18329dcfe8c1SAlbert Zhang 18339dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 18349dcfe8c1SAlbert Zhang { 18359dcfe8c1SAlbert Zhang return false; 18369dcfe8c1SAlbert Zhang } 18379dcfe8c1SAlbert Zhang 18389dcfe8c1SAlbert Zhang return std::nullopt; 18399dcfe8c1SAlbert Zhang } 18409dcfe8c1SAlbert Zhang 18419dcfe8c1SAlbert Zhang /** 18429dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 18439dcfe8c1SAlbert Zhang * 1844fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 18459dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 18469dcfe8c1SAlbert Zhang * 18479dcfe8c1SAlbert Zhang * @return None. 18489dcfe8c1SAlbert Zhang */ 1849fc3edfddSEd Tanous inline void 1850fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 18519dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 18529dcfe8c1SAlbert Zhang { 185362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 18549dcfe8c1SAlbert Zhang 18559dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 18569dcfe8c1SAlbert Zhang if (!stopBootEnabled) 18579dcfe8c1SAlbert Zhang { 185862598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 185962598e31SEd Tanous stopBootOnFault); 1860fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 18619dcfe8c1SAlbert Zhang "StopBootOnFault"); 18629dcfe8c1SAlbert Zhang return; 18639dcfe8c1SAlbert Zhang } 18649dcfe8c1SAlbert Zhang 1865e93abac6SGinu George setDbusProperty(asyncResp, "Boot/StopBootOnFault", 1866e93abac6SGinu George "xyz.openbmc_project.Settings", 186787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 186887c44966SAsmitha Karunanithi "/xyz/openbmc_project/logging/settings"), 1869fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1870e93abac6SGinu George *stopBootEnabled); 18719dcfe8c1SAlbert Zhang } 18729dcfe8c1SAlbert Zhang 18739dcfe8c1SAlbert Zhang /** 187469f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 187569f35306SGunnar Mills * 1876ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 187769f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 187869f35306SGunnar Mills * 187969f35306SGunnar Mills * @return None. 188069f35306SGunnar Mills */ 1881ac106bf6SEd Tanous inline void 1882ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1883f23b7296SEd Tanous const std::string& automaticRetryConfig) 188469f35306SGunnar Mills { 188562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 188669f35306SGunnar Mills 188769f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1888543f4400SEd Tanous bool autoRebootEnabled = false; 188969f35306SGunnar Mills 189069f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 189169f35306SGunnar Mills { 189269f35306SGunnar Mills autoRebootEnabled = false; 189369f35306SGunnar Mills } 189469f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 189569f35306SGunnar Mills { 189669f35306SGunnar Mills autoRebootEnabled = true; 189769f35306SGunnar Mills } 189869f35306SGunnar Mills else 189969f35306SGunnar Mills { 190062598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 190162598e31SEd Tanous automaticRetryConfig); 1902ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 190369f35306SGunnar Mills "AutomaticRetryConfig"); 190469f35306SGunnar Mills return; 190569f35306SGunnar Mills } 190669f35306SGunnar Mills 1907e93abac6SGinu George setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig", 1908e93abac6SGinu George "xyz.openbmc_project.Settings", 190987c44966SAsmitha Karunanithi sdbusplus::message::object_path( 191087c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/auto_reboot"), 191187c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.RebootPolicy", 1912e93abac6SGinu George "AutoReboot", autoRebootEnabled); 191369f35306SGunnar Mills } 191469f35306SGunnar Mills 19158d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 19168d69c668SEd Tanous { 19178d69c668SEd Tanous if (policy == "AlwaysOn") 19188d69c668SEd Tanous { 19198d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 19208d69c668SEd Tanous } 19218d69c668SEd Tanous if (policy == "AlwaysOff") 19228d69c668SEd Tanous { 19238d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 19248d69c668SEd Tanous } 19258d69c668SEd Tanous if (policy == "LastState") 19268d69c668SEd Tanous { 19278d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 19288d69c668SEd Tanous } 19298d69c668SEd Tanous return ""; 19308d69c668SEd Tanous } 19318d69c668SEd Tanous 193269f35306SGunnar Mills /** 1933c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1934c6a620f2SGeorge Liu * 1935ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1936c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1937c6a620f2SGeorge Liu * 1938c6a620f2SGeorge Liu * @return None. 1939c6a620f2SGeorge Liu */ 19408d1b46d7Szhanghch05 inline void 1941ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19428d69c668SEd Tanous std::string_view policy) 1943c6a620f2SGeorge Liu { 194462598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 1945c6a620f2SGeorge Liu 19468d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 1947c6a620f2SGeorge Liu 19488d69c668SEd Tanous if (powerRestorePolicy.empty()) 1949c6a620f2SGeorge Liu { 1950ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 19514e69c904SGunnar Mills "PowerRestorePolicy"); 1952c6a620f2SGeorge Liu return; 1953c6a620f2SGeorge Liu } 1954c6a620f2SGeorge Liu 195587c44966SAsmitha Karunanithi setDbusProperty( 1956e93abac6SGinu George asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings", 195787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 195887c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/power_restore_policy"), 19599ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1960e93abac6SGinu George powerRestorePolicy); 1961c6a620f2SGeorge Liu } 1962c6a620f2SGeorge Liu 1963a6349918SAppaRao Puli /** 1964a6349918SAppaRao Puli * @brief Retrieves provisioning status 1965a6349918SAppaRao Puli * 196625b54dbaSEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous 196725b54dbaSEd Tanous * calls. 1968a6349918SAppaRao Puli * 1969a6349918SAppaRao Puli * @return None. 1970a6349918SAppaRao Puli */ 197125b54dbaSEd Tanous inline void 197225b54dbaSEd Tanous getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1973a6349918SAppaRao Puli { 197462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 1975bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1976bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1977bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 1978ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1979b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1980b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1981bd79bce8SPatrick Williams asyncResp->res 1982bd79bce8SPatrick Williams .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 1983ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 19841d834d49SEd Tanous "#OpenBMCComputerSystem.v1_0_0.OpenBmc"; 1985bd79bce8SPatrick Williams oemPFR["@odata.type"] = 1986bd79bce8SPatrick Williams "#OpenBMCComputerSystem.FirmwareProvisioning"; 198750626f4fSJames Feist 1988a6349918SAppaRao Puli if (ec) 1989a6349918SAppaRao Puli { 199062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1991b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1992539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 1993539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 1994a6349918SAppaRao Puli return; 1995a6349918SAppaRao Puli } 1996a6349918SAppaRao Puli 1997a6349918SAppaRao Puli const bool* provState = nullptr; 1998a6349918SAppaRao Puli const bool* lockState = nullptr; 1999bc1d29deSKrzysztof Grobelny 2000bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2001bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), propertiesList, 2002bd79bce8SPatrick Williams "UfmProvisioned", provState, "UfmLocked", lockState); 2003bc1d29deSKrzysztof Grobelny 2004bc1d29deSKrzysztof Grobelny if (!success) 2005a6349918SAppaRao Puli { 2006ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2007bc1d29deSKrzysztof Grobelny return; 2008a6349918SAppaRao Puli } 2009a6349918SAppaRao Puli 2010a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2011a6349918SAppaRao Puli { 201262598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 2013ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2014a6349918SAppaRao Puli return; 2015a6349918SAppaRao Puli } 2016a6349918SAppaRao Puli 201725b54dbaSEd Tanous if (*provState) 2018a6349918SAppaRao Puli { 201925b54dbaSEd Tanous if (*lockState) 2020a6349918SAppaRao Puli { 2021539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2022539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedAndLocked; 2023a6349918SAppaRao Puli } 2024a6349918SAppaRao Puli else 2025a6349918SAppaRao Puli { 2026539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2027539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedButNotLocked; 2028a6349918SAppaRao Puli } 2029a6349918SAppaRao Puli } 2030a6349918SAppaRao Puli else 2031a6349918SAppaRao Puli { 2032539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2033539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 2034a6349918SAppaRao Puli } 2035bc1d29deSKrzysztof Grobelny }); 2036a6349918SAppaRao Puli } 2037a6349918SAppaRao Puli 2038491d8ee7SSantosh Puranik /** 20396b9ac4f2SChris Cain * @brief Translate the PowerMode string to enum value 20403a2d0424SChris Cain * 20416b9ac4f2SChris Cain * @param[in] modeString PowerMode string to be translated 20423a2d0424SChris Cain * 20436b9ac4f2SChris Cain * @return PowerMode enum 20443a2d0424SChris Cain */ 20456b9ac4f2SChris Cain inline computer_system::PowerMode 20466b9ac4f2SChris Cain translatePowerModeString(const std::string& modeString) 20473a2d0424SChris Cain { 2048b6655101SChris Cain using PowerMode = computer_system::PowerMode; 2049b6655101SChris Cain 20506b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20513a2d0424SChris Cain { 20526b9ac4f2SChris Cain return PowerMode::Static; 20533a2d0424SChris Cain } 20546b9ac4f2SChris Cain if (modeString == 20550fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20563a2d0424SChris Cain { 20576b9ac4f2SChris Cain return PowerMode::MaximumPerformance; 20583a2d0424SChris Cain } 20596b9ac4f2SChris Cain if (modeString == 20600fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20613a2d0424SChris Cain { 20626b9ac4f2SChris Cain return PowerMode::PowerSaving; 2063b6655101SChris Cain } 20646b9ac4f2SChris Cain if (modeString == 2065b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance") 2066b6655101SChris Cain { 20676b9ac4f2SChris Cain return PowerMode::BalancedPerformance; 2068b6655101SChris Cain } 20696b9ac4f2SChris Cain if (modeString == 2070b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance") 2071b6655101SChris Cain { 20726b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPerformance; 2073b6655101SChris Cain } 20746b9ac4f2SChris Cain if (modeString == 2075b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower") 2076b6655101SChris Cain { 20776b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPower; 20783a2d0424SChris Cain } 20796b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20803a2d0424SChris Cain { 20816b9ac4f2SChris Cain return PowerMode::OEM; 20826b9ac4f2SChris Cain } 20836b9ac4f2SChris Cain // Any other values would be invalid 20846b9ac4f2SChris Cain BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString); 20856b9ac4f2SChris Cain return PowerMode::Invalid; 20866b9ac4f2SChris Cain } 20876b9ac4f2SChris Cain 20886b9ac4f2SChris Cain inline void 20896b9ac4f2SChris Cain afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20906b9ac4f2SChris Cain const boost::system::error_code& ec, 20916b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) 20926b9ac4f2SChris Cain { 20936b9ac4f2SChris Cain if (ec) 20946b9ac4f2SChris Cain { 20956b9ac4f2SChris Cain BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec); 20966b9ac4f2SChris Cain messages::internalError(asyncResp->res); 20976b9ac4f2SChris Cain return; 20986b9ac4f2SChris Cain } 20996b9ac4f2SChris Cain 21006b9ac4f2SChris Cain std::string powerMode; 21016b9ac4f2SChris Cain const std::vector<std::string>* allowedModes = nullptr; 21026b9ac4f2SChris Cain const bool success = sdbusplus::unpackPropertiesNoThrow( 21036b9ac4f2SChris Cain dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode, 21046b9ac4f2SChris Cain "AllowedPowerModes", allowedModes); 21056b9ac4f2SChris Cain 21066b9ac4f2SChris Cain if (!success) 21076b9ac4f2SChris Cain { 21086b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21096b9ac4f2SChris Cain return; 21106b9ac4f2SChris Cain } 21116b9ac4f2SChris Cain 21126b9ac4f2SChris Cain nlohmann::json::array_t modeList; 21136b9ac4f2SChris Cain if (allowedModes == nullptr) 21146b9ac4f2SChris Cain { 21156b9ac4f2SChris Cain modeList.emplace_back("Static"); 21166b9ac4f2SChris Cain modeList.emplace_back("MaximumPerformance"); 21176b9ac4f2SChris Cain modeList.emplace_back("PowerSaving"); 21183a2d0424SChris Cain } 21193a2d0424SChris Cain else 21203a2d0424SChris Cain { 21216b9ac4f2SChris Cain for (const auto& aMode : *allowedModes) 21226b9ac4f2SChris Cain { 21236b9ac4f2SChris Cain computer_system::PowerMode modeValue = 21246b9ac4f2SChris Cain translatePowerModeString(aMode); 21256b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21266b9ac4f2SChris Cain { 2127ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21286b9ac4f2SChris Cain continue; 21296b9ac4f2SChris Cain } 21306b9ac4f2SChris Cain modeList.emplace_back(modeValue); 21313a2d0424SChris Cain } 21323a2d0424SChris Cain } 21336b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList; 21343a2d0424SChris Cain 21356b9ac4f2SChris Cain BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode); 21366b9ac4f2SChris Cain const computer_system::PowerMode modeValue = 21376b9ac4f2SChris Cain translatePowerModeString(powerMode); 21386b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21396b9ac4f2SChris Cain { 21406b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21416b9ac4f2SChris Cain return; 21426b9ac4f2SChris Cain } 21436b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode"] = modeValue; 21446b9ac4f2SChris Cain } 21453a2d0424SChris Cain /** 21463a2d0424SChris Cain * @brief Retrieves system power mode 21473a2d0424SChris Cain * 2148ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21493a2d0424SChris Cain * 21503a2d0424SChris Cain * @return None. 21513a2d0424SChris Cain */ 2152ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 21533a2d0424SChris Cain { 215462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 21553a2d0424SChris Cain 21563a2d0424SChris Cain // Get Power Mode object path: 2157e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2158e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2159e99073f5SGeorge Liu dbus::utility::getSubTree( 2160e99073f5SGeorge Liu "/", 0, interfaces, 2161ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2162b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21633a2d0424SChris Cain if (ec) 21643a2d0424SChris Cain { 2165bd79bce8SPatrick Williams BMCWEB_LOG_DEBUG( 2166bd79bce8SPatrick Williams "DBUS response error on Power.Mode GetSubTree {}", ec); 21673a2d0424SChris Cain // This is an optional D-Bus object so just return if 21683a2d0424SChris Cain // error occurs 21693a2d0424SChris Cain return; 21703a2d0424SChris Cain } 21713a2d0424SChris Cain if (subtree.empty()) 21723a2d0424SChris Cain { 21733a2d0424SChris Cain // As noted above, this is an optional interface so just return 21743a2d0424SChris Cain // if there is no instance found 21753a2d0424SChris Cain return; 21763a2d0424SChris Cain } 21773a2d0424SChris Cain if (subtree.size() > 1) 21783a2d0424SChris Cain { 21793a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21803a2d0424SChris Cain // error 218162598e31SEd Tanous BMCWEB_LOG_DEBUG( 218262598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 218362598e31SEd Tanous subtree.size()); 2184ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21853a2d0424SChris Cain return; 21863a2d0424SChris Cain } 21873a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21883a2d0424SChris Cain { 218962598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2190ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21913a2d0424SChris Cain return; 21923a2d0424SChris Cain } 21933a2d0424SChris Cain const std::string& path = subtree[0].first; 21943a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21953a2d0424SChris Cain if (service.empty()) 21963a2d0424SChris Cain { 219762598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2198ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21993a2d0424SChris Cain return; 22003a2d0424SChris Cain } 22016b9ac4f2SChris Cain 22026b9ac4f2SChris Cain // Valid Power Mode object found, now read the mode properties 22036b9ac4f2SChris Cain sdbusplus::asio::getAllProperties( 22041e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 22056b9ac4f2SChris Cain "xyz.openbmc_project.Control.Power.Mode", 2206bd79bce8SPatrick Williams [asyncResp]( 2207bd79bce8SPatrick Williams const boost::system::error_code& ec2, 22086b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 22096b9ac4f2SChris Cain afterGetPowerMode(asyncResp, ec2, properties); 22101e1e598dSJonathan Doman }); 2211e99073f5SGeorge Liu }); 22123a2d0424SChris Cain } 22133a2d0424SChris Cain 22143a2d0424SChris Cain /** 22153a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 22163a2d0424SChris Cain * name associated with that string 22173a2d0424SChris Cain * 2218ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2219b6655101SChris Cain * @param[in] modeValue String representing the desired PowerMode 22203a2d0424SChris Cain * 22213a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22223a2d0424SChris Cain */ 22233a2d0424SChris Cain inline std::string 2224ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2225b6655101SChris Cain const nlohmann::json& modeValue) 22263a2d0424SChris Cain { 2227b6655101SChris Cain using PowerMode = computer_system::PowerMode; 22283a2d0424SChris Cain std::string mode; 22293a2d0424SChris Cain 2230b6655101SChris Cain if (modeValue == PowerMode::Static) 22313a2d0424SChris Cain { 22323a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22333a2d0424SChris Cain } 2234b6655101SChris Cain else if (modeValue == PowerMode::MaximumPerformance) 22353a2d0424SChris Cain { 22360fda0f12SGeorge Liu mode = 22370fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 22383a2d0424SChris Cain } 2239b6655101SChris Cain else if (modeValue == PowerMode::PowerSaving) 22403a2d0424SChris Cain { 22413a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22423a2d0424SChris Cain } 2243b6655101SChris Cain else if (modeValue == PowerMode::BalancedPerformance) 2244b6655101SChris Cain { 2245b6655101SChris Cain mode = 2246b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance"; 2247b6655101SChris Cain } 2248b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPerformance) 2249b6655101SChris Cain { 2250b6655101SChris Cain mode = 2251b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance"; 2252b6655101SChris Cain } 2253b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPower) 2254b6655101SChris Cain { 2255b6655101SChris Cain mode = 2256b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower"; 2257b6655101SChris Cain } 22583a2d0424SChris Cain else 22593a2d0424SChris Cain { 2260b6655101SChris Cain messages::propertyValueNotInList(asyncResp->res, modeValue.dump(), 2261ac106bf6SEd Tanous "PowerMode"); 22623a2d0424SChris Cain } 22633a2d0424SChris Cain return mode; 22643a2d0424SChris Cain } 22653a2d0424SChris Cain 22663a2d0424SChris Cain /** 22673a2d0424SChris Cain * @brief Sets system power mode. 22683a2d0424SChris Cain * 2269ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22703a2d0424SChris Cain * @param[in] pmode System power mode from request. 22713a2d0424SChris Cain * 22723a2d0424SChris Cain * @return None. 22733a2d0424SChris Cain */ 2274ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22753a2d0424SChris Cain const std::string& pmode) 22763a2d0424SChris Cain { 227762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 22783a2d0424SChris Cain 2279ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 22803a2d0424SChris Cain if (powerMode.empty()) 22813a2d0424SChris Cain { 22823a2d0424SChris Cain return; 22833a2d0424SChris Cain } 22843a2d0424SChris Cain 22853a2d0424SChris Cain // Get Power Mode object path: 2286e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2287e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2288e99073f5SGeorge Liu dbus::utility::getSubTree( 2289e99073f5SGeorge Liu "/", 0, interfaces, 2290ac106bf6SEd Tanous [asyncResp, 2291e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2292b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22933a2d0424SChris Cain if (ec) 22943a2d0424SChris Cain { 2295bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 2296bd79bce8SPatrick Williams "DBUS response error on Power.Mode GetSubTree {}", ec); 22973a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2298ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22993a2d0424SChris Cain return; 23003a2d0424SChris Cain } 23013a2d0424SChris Cain if (subtree.empty()) 23023a2d0424SChris Cain { 23033a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2304ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 23053a2d0424SChris Cain "PowerMode"); 23063a2d0424SChris Cain return; 23073a2d0424SChris Cain } 23083a2d0424SChris Cain if (subtree.size() > 1) 23093a2d0424SChris Cain { 23103a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23113a2d0424SChris Cain // error 231262598e31SEd Tanous BMCWEB_LOG_DEBUG( 231362598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 231462598e31SEd Tanous subtree.size()); 2315ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23163a2d0424SChris Cain return; 23173a2d0424SChris Cain } 23183a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23193a2d0424SChris Cain { 232062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2321ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23223a2d0424SChris Cain return; 23233a2d0424SChris Cain } 23243a2d0424SChris Cain const std::string& path = subtree[0].first; 23253a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23263a2d0424SChris Cain if (service.empty()) 23273a2d0424SChris Cain { 232862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2329ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23303a2d0424SChris Cain return; 23313a2d0424SChris Cain } 23323a2d0424SChris Cain 233362598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 23343a2d0424SChris Cain 23353a2d0424SChris Cain // Set the Power Mode property 2336e93abac6SGinu George setDbusProperty(asyncResp, "PowerMode", service, path, 2337bd79bce8SPatrick Williams "xyz.openbmc_project.Control.Power.Mode", 2338bd79bce8SPatrick Williams "PowerMode", powerMode); 2339e99073f5SGeorge Liu }); 23403a2d0424SChris Cain } 23413a2d0424SChris Cain 23423a2d0424SChris Cain /** 234351709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 234451709ffdSYong Li * 234551709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 234651709ffdSYong Li * 234751709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 234851709ffdSYong Li * translation cannot be done, returns an empty string. 234951709ffdSYong Li */ 235023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 235151709ffdSYong Li { 235251709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 235351709ffdSYong Li { 235451709ffdSYong Li return "None"; 235551709ffdSYong Li } 23563174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 235751709ffdSYong Li { 235851709ffdSYong Li return "ResetSystem"; 235951709ffdSYong Li } 23603174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 236151709ffdSYong Li { 236251709ffdSYong Li return "PowerDown"; 236351709ffdSYong Li } 23643174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 236551709ffdSYong Li { 236651709ffdSYong Li return "PowerCycle"; 236751709ffdSYong Li } 236851709ffdSYong Li 236951709ffdSYong Li return ""; 237051709ffdSYong Li } 237151709ffdSYong Li 237251709ffdSYong Li /** 2373c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2374c45f0082SYong Li * 2375c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2376c45f0082SYong Li * 2377c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2378c45f0082SYong Li *If translation cannot be done, returns an empty string. 2379c45f0082SYong Li */ 2380c45f0082SYong Li 238123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2382c45f0082SYong Li { 2383c45f0082SYong Li if (rfAction == "None") 2384c45f0082SYong Li { 2385c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2386c45f0082SYong Li } 23873174e4dfSEd Tanous if (rfAction == "PowerCycle") 2388c45f0082SYong Li { 2389c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2390c45f0082SYong Li } 23913174e4dfSEd Tanous if (rfAction == "PowerDown") 2392c45f0082SYong Li { 2393c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2394c45f0082SYong Li } 23953174e4dfSEd Tanous if (rfAction == "ResetSystem") 2396c45f0082SYong Li { 2397c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2398c45f0082SYong Li } 2399c45f0082SYong Li 2400c45f0082SYong Li return ""; 2401c45f0082SYong Li } 2402c45f0082SYong Li 2403c45f0082SYong Li /** 240451709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 240551709ffdSYong Li * 2406ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 240751709ffdSYong Li * 240851709ffdSYong Li * @return None. 240951709ffdSYong Li */ 24108d1b46d7Szhanghch05 inline void 2411ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 241251709ffdSYong Li { 241362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2414bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2415bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2416bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2417bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2418ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2419b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 242051709ffdSYong Li if (ec) 242151709ffdSYong Li { 242251709ffdSYong Li // watchdog service is stopped 242362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 242451709ffdSYong Li return; 242551709ffdSYong Li } 242651709ffdSYong Li 242762598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 242851709ffdSYong Li 242951709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2430ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 243151709ffdSYong Li 243251709ffdSYong Li // watchdog service is running/enabled 2433539d8c6bSEd Tanous hostWatchdogTimer["Status"]["State"] = resource::State::Enabled; 243451709ffdSYong Li 2435bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2436bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 243751709ffdSYong Li 2438bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2439bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), properties, "Enabled", 2440bd79bce8SPatrick Williams enabled, "ExpireAction", expireAction); 2441bc1d29deSKrzysztof Grobelny 2442bc1d29deSKrzysztof Grobelny if (!success) 244351709ffdSYong Li { 2444ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2445601af5edSChicago Duan return; 244651709ffdSYong Li } 244751709ffdSYong Li 2448bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 244951709ffdSYong Li { 2450bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 245151709ffdSYong Li } 245251709ffdSYong Li 2453bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2454bc1d29deSKrzysztof Grobelny { 2455bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 245651709ffdSYong Li if (action.empty()) 245751709ffdSYong Li { 2458ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2459601af5edSChicago Duan return; 246051709ffdSYong Li } 246151709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 246251709ffdSYong Li } 2463bc1d29deSKrzysztof Grobelny }); 246451709ffdSYong Li } 246551709ffdSYong Li 246651709ffdSYong Li /** 2467c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2468c45f0082SYong Li * 2469ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2470c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2471c45f0082SYong Li * RF request. 2472c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2473c45f0082SYong Li * 2474c45f0082SYong Li * @return None. 2475c45f0082SYong Li */ 2476ac106bf6SEd Tanous inline void 2477ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2478c45f0082SYong Li const std::optional<bool> wdtEnable, 2479c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2480c45f0082SYong Li { 248162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2482c45f0082SYong Li 2483c45f0082SYong Li if (wdtTimeOutAction) 2484c45f0082SYong Li { 2485c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2486c45f0082SYong Li // check if TimeOut Action is Valid 2487c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2488c45f0082SYong Li { 248962598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 249062598e31SEd Tanous *wdtTimeOutAction); 2491ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2492c45f0082SYong Li "TimeoutAction"); 2493c45f0082SYong Li return; 2494c45f0082SYong Li } 2495c45f0082SYong Li 2496e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction", 2497e93abac6SGinu George "xyz.openbmc_project.Watchdog", 249887c44966SAsmitha Karunanithi sdbusplus::message::object_path( 249987c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 25009ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2501e93abac6SGinu George wdtTimeOutActStr); 2502c45f0082SYong Li } 2503c45f0082SYong Li 2504c45f0082SYong Li if (wdtEnable) 2505c45f0082SYong Li { 2506e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled", 2507e93abac6SGinu George "xyz.openbmc_project.Watchdog", 250887c44966SAsmitha Karunanithi sdbusplus::message::object_path( 250987c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 251087c44966SAsmitha Karunanithi "xyz.openbmc_project.State.Watchdog", "Enabled", 2511e93abac6SGinu George *wdtEnable); 2512c45f0082SYong Li } 2513c45f0082SYong Li } 2514c45f0082SYong Li 251537bbf98cSChris Cain /** 251637bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 251737bbf98cSChris Cain * 2518ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 251937bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 252037bbf98cSChris Cain * 252137bbf98cSChris Cain * @return true if successful 252237bbf98cSChris Cain */ 25231e5b7c88SJiaqing Zhao inline bool 2524ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25251e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 252637bbf98cSChris Cain { 2527bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2528bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2529bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2530bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2531bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2532bc1d29deSKrzysztof Grobelny 2533bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2534bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 25352661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 25362661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 25372661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2538bc1d29deSKrzysztof Grobelny 2539bc1d29deSKrzysztof Grobelny if (!success) 254037bbf98cSChris Cain { 254137bbf98cSChris Cain return false; 254237bbf98cSChris Cain } 2543bc1d29deSKrzysztof Grobelny 2544bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 254537bbf98cSChris Cain { 2546ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 254737bbf98cSChris Cain } 2548bc1d29deSKrzysztof Grobelny 2549bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 255037bbf98cSChris Cain { 2551ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2552bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 255337bbf98cSChris Cain } 2554bc1d29deSKrzysztof Grobelny 2555bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2556bc1d29deSKrzysztof Grobelny { 2557bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2558ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 255937bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 256037bbf98cSChris Cain .count(); 256137bbf98cSChris Cain } 2562bc1d29deSKrzysztof Grobelny 2563bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 256437bbf98cSChris Cain { 2565ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2566bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 256737bbf98cSChris Cain } 2568bc1d29deSKrzysztof Grobelny 2569bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 257037bbf98cSChris Cain { 2571bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2572ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 257337bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 257437bbf98cSChris Cain .count(); 257537bbf98cSChris Cain } 257637bbf98cSChris Cain 257737bbf98cSChris Cain return true; 257837bbf98cSChris Cain } 257937bbf98cSChris Cain 258037bbf98cSChris Cain /** 258137bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 258237bbf98cSChris Cain * 2583ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 258437bbf98cSChris Cain * 258537bbf98cSChris Cain * @return None. 258637bbf98cSChris Cain */ 2587ac106bf6SEd Tanous inline void 2588ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 258937bbf98cSChris Cain { 259062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 259137bbf98cSChris Cain 259237bbf98cSChris Cain // Get IdlePowerSaver object path: 2593e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2594e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2595e99073f5SGeorge Liu dbus::utility::getSubTree( 2596e99073f5SGeorge Liu "/", 0, interfaces, 2597ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2598b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 259937bbf98cSChris Cain if (ec) 260037bbf98cSChris Cain { 2601b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 260262598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 260362598e31SEd Tanous ec); 2604ac106bf6SEd Tanous messages::internalError(asyncResp->res); 260537bbf98cSChris Cain return; 260637bbf98cSChris Cain } 260737bbf98cSChris Cain if (subtree.empty()) 260837bbf98cSChris Cain { 260937bbf98cSChris Cain // This is an optional interface so just return 261037bbf98cSChris Cain // if there is no instance found 261162598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 261237bbf98cSChris Cain return; 261337bbf98cSChris Cain } 261437bbf98cSChris Cain if (subtree.size() > 1) 261537bbf98cSChris Cain { 261637bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 261737bbf98cSChris Cain // is an error 261862598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 261962598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 262062598e31SEd Tanous subtree.size()); 2621ac106bf6SEd Tanous messages::internalError(asyncResp->res); 262237bbf98cSChris Cain return; 262337bbf98cSChris Cain } 262437bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 262537bbf98cSChris Cain { 262662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2627ac106bf6SEd Tanous messages::internalError(asyncResp->res); 262837bbf98cSChris Cain return; 262937bbf98cSChris Cain } 263037bbf98cSChris Cain const std::string& path = subtree[0].first; 263137bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 263237bbf98cSChris Cain if (service.empty()) 263337bbf98cSChris Cain { 263462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2635ac106bf6SEd Tanous messages::internalError(asyncResp->res); 263637bbf98cSChris Cain return; 263737bbf98cSChris Cain } 263837bbf98cSChris Cain 263937bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2640bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2641bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2642bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2643bd79bce8SPatrick Williams [asyncResp]( 2644bd79bce8SPatrick Williams const boost::system::error_code& ec2, 26451e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 26468a592810SEd Tanous if (ec2) 264737bbf98cSChris Cain { 264862598e31SEd Tanous BMCWEB_LOG_ERROR( 2649bd79bce8SPatrick Williams "DBUS response error on IdlePowerSaver GetAll: {}", 2650bd79bce8SPatrick Williams ec2); 2651ac106bf6SEd Tanous messages::internalError(asyncResp->res); 265237bbf98cSChris Cain return; 265337bbf98cSChris Cain } 265437bbf98cSChris Cain 2655ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 265637bbf98cSChris Cain { 2657ac106bf6SEd Tanous messages::internalError(asyncResp->res); 265837bbf98cSChris Cain return; 265937bbf98cSChris Cain } 2660bc1d29deSKrzysztof Grobelny }); 2661e99073f5SGeorge Liu }); 266237bbf98cSChris Cain 266362598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 266437bbf98cSChris Cain } 266537bbf98cSChris Cain 266637bbf98cSChris Cain /** 266737bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 266837bbf98cSChris Cain * 2669ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 267037bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 267137bbf98cSChris Cain * RF request. 267237bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 267337bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 267437bbf98cSChris Cain * before entering idle state. 267537bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 267637bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 267737bbf98cSChris Cain * before exiting idle state 267837bbf98cSChris Cain * 267937bbf98cSChris Cain * @return None. 268037bbf98cSChris Cain */ 2681bd79bce8SPatrick Williams inline void setIdlePowerSaver( 2682bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 268337bbf98cSChris Cain const std::optional<bool> ipsEnable, 268437bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 268537bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 268637bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 268737bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 268837bbf98cSChris Cain { 268962598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 269037bbf98cSChris Cain 269137bbf98cSChris Cain // Get IdlePowerSaver object path: 2692e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2693e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2694e99073f5SGeorge Liu dbus::utility::getSubTree( 2695e99073f5SGeorge Liu "/", 0, interfaces, 2696ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2697e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2698b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 269937bbf98cSChris Cain if (ec) 270037bbf98cSChris Cain { 2701b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 270262598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 270362598e31SEd Tanous ec); 2704ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270537bbf98cSChris Cain return; 270637bbf98cSChris Cain } 270737bbf98cSChris Cain if (subtree.empty()) 270837bbf98cSChris Cain { 270937bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2710ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 271137bbf98cSChris Cain "IdlePowerSaver"); 271237bbf98cSChris Cain return; 271337bbf98cSChris Cain } 271437bbf98cSChris Cain if (subtree.size() > 1) 271537bbf98cSChris Cain { 271637bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 271737bbf98cSChris Cain // is an error 271862598e31SEd Tanous BMCWEB_LOG_DEBUG( 271962598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 272062598e31SEd Tanous subtree.size()); 2721ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272237bbf98cSChris Cain return; 272337bbf98cSChris Cain } 272437bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 272537bbf98cSChris Cain { 272662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2727ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272837bbf98cSChris Cain return; 272937bbf98cSChris Cain } 273037bbf98cSChris Cain const std::string& path = subtree[0].first; 273137bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 273237bbf98cSChris Cain if (service.empty()) 273337bbf98cSChris Cain { 273462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2735ac106bf6SEd Tanous messages::internalError(asyncResp->res); 273637bbf98cSChris Cain return; 273737bbf98cSChris Cain } 273837bbf98cSChris Cain 273937bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 274037bbf98cSChris Cain // need to be updated 274137bbf98cSChris Cain 274237bbf98cSChris Cain if (ipsEnable) 274337bbf98cSChris Cain { 2744bd79bce8SPatrick Williams setDbusProperty( 2745bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/Enabled", service, path, 274687c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2747e93abac6SGinu George "Enabled", *ipsEnable); 274837bbf98cSChris Cain } 274937bbf98cSChris Cain if (ipsEnterUtil) 275037bbf98cSChris Cain { 2751bd79bce8SPatrick Williams setDbusProperty( 2752bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/EnterUtilizationPercent", 2753e93abac6SGinu George service, path, 27549ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2755e93abac6SGinu George "EnterUtilizationPercent", *ipsEnterUtil); 275637bbf98cSChris Cain } 275737bbf98cSChris Cain if (ipsEnterTime) 275837bbf98cSChris Cain { 275937bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 276037bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 2761bd79bce8SPatrick Williams setDbusProperty( 2762bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service, 2763bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2764e93abac6SGinu George "EnterDwellTime", timeMilliseconds); 276537bbf98cSChris Cain } 276637bbf98cSChris Cain if (ipsExitUtil) 276737bbf98cSChris Cain { 2768bd79bce8SPatrick Williams setDbusProperty( 2769bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service, 2770bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2771e93abac6SGinu George "ExitUtilizationPercent", *ipsExitUtil); 277237bbf98cSChris Cain } 277337bbf98cSChris Cain if (ipsExitTime) 277437bbf98cSChris Cain { 277537bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 277637bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 2777bd79bce8SPatrick Williams setDbusProperty( 2778bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service, 2779bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2780e93abac6SGinu George "ExitDwellTime", timeMilliseconds); 278137bbf98cSChris Cain } 2782e99073f5SGeorge Liu }); 278337bbf98cSChris Cain 278462598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 278537bbf98cSChris Cain } 278637bbf98cSChris Cain 2787c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2788dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2789dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2790dd60b9edSEd Tanous { 2791dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2792dd60b9edSEd Tanous { 2793dd60b9edSEd Tanous return; 2794dd60b9edSEd Tanous } 2795dd60b9edSEd Tanous asyncResp->res.addHeader( 2796dd60b9edSEd Tanous boost::beast::http::field::link, 2797dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2798dd60b9edSEd Tanous } 2799dd60b9edSEd Tanous 2800c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2801c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2802c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28031abe55efSEd Tanous { 28043ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2805f4c99e70SEd Tanous { 2806f4c99e70SEd Tanous return; 2807f4c99e70SEd Tanous } 2808dd60b9edSEd Tanous 2809dd60b9edSEd Tanous asyncResp->res.addHeader( 2810dd60b9edSEd Tanous boost::beast::http::field::link, 2811dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 28128d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28130f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28148d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28158d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2816462023adSSunitha Harish 28177f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 28187f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 281925b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 28207f3e84a1SEd Tanous { 28217f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 28227f3e84a1SEd Tanous // Option currently returns no systems. TBD 28237f3e84a1SEd Tanous return; 28247f3e84a1SEd Tanous } 28257f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 28267f3e84a1SEd Tanous nlohmann::json::object_t system; 2827253f11b8SEd Tanous system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}", 2828253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 28297f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 283068896206SGunnar Mills 283168896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 2832462023adSSunitha Harish { 283362598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 283468896206SGunnar Mills asyncResp->res.jsonValue["Members@odata.count"] = 2; 283568896206SGunnar Mills 28361476687dSEd Tanous nlohmann::json::object_t hypervisor; 2837002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 283868896206SGunnar Mills ifaceArray.emplace_back(std::move(hypervisor)); 283968896206SGunnar Mills } 2840c1e219d5SEd Tanous } 2841c1e219d5SEd Tanous 2842c1e219d5SEd Tanous /** 28437e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28447e860f15SJohn Edward Broadbent */ 28454f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28467e860f15SJohn Edward Broadbent { 284789492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 284889492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 284989492a15SPatrick Williams constexpr const char* interfaceName = 28507e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 285189492a15SPatrick Williams constexpr const char* method = "NMI"; 28527e860f15SJohn Edward Broadbent 28537e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28545e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28557e860f15SJohn Edward Broadbent if (ec) 28567e860f15SJohn Edward Broadbent { 285762598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 28587e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28597e860f15SJohn Edward Broadbent return; 28607e860f15SJohn Edward Broadbent } 28617e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28627e860f15SJohn Edward Broadbent }, 28637e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28647e860f15SJohn Edward Broadbent } 2865c5b2abe0SLewanczyk, Dawid 2866c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2867c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 28687f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2869c1e219d5SEd Tanous const std::string& systemName) 2870c1e219d5SEd Tanous { 28713ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 287245ca1b86SEd Tanous { 287345ca1b86SEd Tanous return; 287445ca1b86SEd Tanous } 2875*dd7090e6SGunnar Mills 2876*dd7090e6SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 2877*dd7090e6SGunnar Mills { 2878*dd7090e6SGunnar Mills if (systemName == "hypervisor") 2879*dd7090e6SGunnar Mills { 2880*dd7090e6SGunnar Mills handleHypervisorSystemResetPost(req, asyncResp); 2881*dd7090e6SGunnar Mills return; 2882*dd7090e6SGunnar Mills } 2883*dd7090e6SGunnar Mills } 2884*dd7090e6SGunnar Mills 2885253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 2886c1e219d5SEd Tanous { 2887c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2888c1e219d5SEd Tanous systemName); 2889c1e219d5SEd Tanous return; 2890c1e219d5SEd Tanous } 289125b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 28927f3e84a1SEd Tanous { 28937f3e84a1SEd Tanous // Option currently returns no systems. TBD 28947f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2895c1e219d5SEd Tanous systemName); 28967f3e84a1SEd Tanous return; 28977f3e84a1SEd Tanous } 28989712f8acSEd Tanous std::string resetType; 2899c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 2900cc340dd9SEd Tanous { 2901cc340dd9SEd Tanous return; 2902cc340dd9SEd Tanous } 2903cc340dd9SEd Tanous 2904d22c8396SJason M. Bills // Get the command and host vs. chassis 2905cc340dd9SEd Tanous std::string command; 2906543f4400SEd Tanous bool hostCommand = true; 2907d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2908cc340dd9SEd Tanous { 2909cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2910d22c8396SJason M. Bills hostCommand = true; 2911d22c8396SJason M. Bills } 2912d22c8396SJason M. Bills else if (resetType == "ForceOff") 2913d22c8396SJason M. Bills { 2914d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2915d22c8396SJason M. Bills hostCommand = false; 2916d22c8396SJason M. Bills } 2917d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2918d22c8396SJason M. Bills { 2919c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 292086a0851aSJason M. Bills hostCommand = true; 2921cc340dd9SEd Tanous } 29229712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2923cc340dd9SEd Tanous { 2924cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2925d22c8396SJason M. Bills hostCommand = true; 2926cc340dd9SEd Tanous } 29279712f8acSEd Tanous else if (resetType == "GracefulRestart") 2928cc340dd9SEd Tanous { 29290fda0f12SGeorge Liu command = 29300fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2931d22c8396SJason M. Bills hostCommand = true; 2932d22c8396SJason M. Bills } 2933d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2934d22c8396SJason M. Bills { 293586a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 293686a0851aSJason M. Bills hostCommand = true; 2937cc340dd9SEd Tanous } 2938bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2939bfd5b826SLakshminarayana R. Kammath { 2940bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2941bfd5b826SLakshminarayana R. Kammath return; 2942bfd5b826SLakshminarayana R. Kammath } 2943cc340dd9SEd Tanous else 2944cc340dd9SEd Tanous { 2945c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 2946cc340dd9SEd Tanous return; 2947cc340dd9SEd Tanous } 2948d02aad39SEd Tanous sdbusplus::message::object_path statePath("/xyz/openbmc_project/state"); 2949cc340dd9SEd Tanous 2950d22c8396SJason M. Bills if (hostCommand) 2951d22c8396SJason M. Bills { 2952e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host", 2953d02aad39SEd Tanous statePath / "host0", "xyz.openbmc_project.State.Host", 2954e93abac6SGinu George "RequestedHostTransition", command); 2955cc340dd9SEd Tanous } 2956d22c8396SJason M. Bills else 2957d22c8396SJason M. Bills { 2958e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis", 2959d02aad39SEd Tanous statePath / "chassis0", 2960d02aad39SEd Tanous "xyz.openbmc_project.State.Chassis", 2961e93abac6SGinu George "RequestedPowerTransition", command); 2962d22c8396SJason M. Bills } 2963d22c8396SJason M. Bills } 2964cc340dd9SEd Tanous 2965c1e219d5SEd Tanous inline void handleComputerSystemHead( 2966dd60b9edSEd Tanous App& app, const crow::Request& req, 29677f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29687f3e84a1SEd Tanous const std::string& /*systemName*/) 2969dd60b9edSEd Tanous { 2970dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2971dd60b9edSEd Tanous { 2972dd60b9edSEd Tanous return; 2973dd60b9edSEd Tanous } 2974dd60b9edSEd Tanous 2975dd60b9edSEd Tanous asyncResp->res.addHeader( 2976dd60b9edSEd Tanous boost::beast::http::field::link, 2977dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2978dd60b9edSEd Tanous } 2979dd60b9edSEd Tanous 29805c3e9272SAbhishek Patel inline void afterPortRequest( 29815c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29825c3e9272SAbhishek Patel const boost::system::error_code& ec, 29835c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 29845c3e9272SAbhishek Patel { 29855c3e9272SAbhishek Patel if (ec) 29865c3e9272SAbhishek Patel { 2987b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 29885c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29895c3e9272SAbhishek Patel return; 29905c3e9272SAbhishek Patel } 29915c3e9272SAbhishek Patel for (const auto& data : socketData) 29925c3e9272SAbhishek Patel { 29935c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 29945c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 29955c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 29965c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 29975c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 29985c3e9272SAbhishek Patel // need to retrieve port number for 29995c3e9272SAbhishek Patel // obmc-console-ssh service 30005c3e9272SAbhishek Patel if (protocolName == "SSH") 30015c3e9272SAbhishek Patel { 30025c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 300381c4e330SEd Tanous const boost::system::error_code& ec1, 30045c3e9272SAbhishek Patel int portNumber) { 30055c3e9272SAbhishek Patel if (ec1) 30065c3e9272SAbhishek Patel { 3007b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 30085c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 30095c3e9272SAbhishek Patel return; 30105c3e9272SAbhishek Patel } 30115c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 30125c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 30135c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 30145c3e9272SAbhishek Patel }); 30155c3e9272SAbhishek Patel } 30165c3e9272SAbhishek Patel } 30175c3e9272SAbhishek Patel } 3018c1e219d5SEd Tanous 3019c1e219d5SEd Tanous inline void 3020c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 302122d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3022c1e219d5SEd Tanous const std::string& systemName) 3023c1e219d5SEd Tanous { 30243ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 302545ca1b86SEd Tanous { 302645ca1b86SEd Tanous return; 302745ca1b86SEd Tanous } 3028746b56f3SAsmitha Karunanithi 302925b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 30307f3e84a1SEd Tanous { 30317f3e84a1SEd Tanous // Option currently returns no systems. TBD 30327f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 30337f3e84a1SEd Tanous systemName); 30347f3e84a1SEd Tanous return; 30357f3e84a1SEd Tanous } 30367f3e84a1SEd Tanous 303768896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 303868896206SGunnar Mills { 3039746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3040746b56f3SAsmitha Karunanithi { 3041746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3042746b56f3SAsmitha Karunanithi return; 3043746b56f3SAsmitha Karunanithi } 304468896206SGunnar Mills } 3045746b56f3SAsmitha Karunanithi 3046253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 304722d268cbSEd Tanous { 304822d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 304922d268cbSEd Tanous systemName); 305022d268cbSEd Tanous return; 305122d268cbSEd Tanous } 3052dd60b9edSEd Tanous asyncResp->res.addHeader( 3053dd60b9edSEd Tanous boost::beast::http::field::link, 3054dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 30558d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3056b6655101SChris Cain "#ComputerSystem.v1_22_0.ComputerSystem"; 3057253f11b8SEd Tanous asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3058253f11b8SEd Tanous asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3059539d8c6bSEd Tanous asyncResp->res.jsonValue["SystemType"] = 3060539d8c6bSEd Tanous computer_system::SystemType::Physical; 30618d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 30628d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 3063cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3064dfb2b408SPriyanga Ramasamy double(0); 3065253f11b8SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 3066253f11b8SEd Tanous "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME); 306704a258f4SEd Tanous 3068253f11b8SEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format( 3069253f11b8SEd Tanous "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3070253f11b8SEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format( 3071253f11b8SEd Tanous "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3072253f11b8SEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format( 3073253f11b8SEd Tanous "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME); 30743179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 3075253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters", 3076253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3077029573d4SEd Tanous 3078002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 3079253f11b8SEd Tanous boost::urls::format( 3080253f11b8SEd Tanous "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", 3081253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3082c1e219d5SEd Tanous asyncResp->res 3083c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 3084253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3085253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3086c5b2abe0SLewanczyk, Dawid 3087253f11b8SEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format( 3088253f11b8SEd Tanous "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3089253f11b8SEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format( 3090253f11b8SEd Tanous "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3091c4bf6374SJason M. Bills 30921476687dSEd Tanous nlohmann::json::array_t managedBy; 30931476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 3094253f11b8SEd Tanous manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}", 3095253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME); 3096002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 3097539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK; 3098539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled; 30990e8ac5e7SGunnar Mills 31000e8ac5e7SGunnar Mills // Fill in SerialConsole info 3101002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3102c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 31031476687dSEd Tanous 3104c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 31051476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3106c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 31071476687dSEd Tanous "Press ~. to exit console"; 31085c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 31095c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 31100e8ac5e7SGunnar Mills 311125b54dbaSEd Tanous if constexpr (BMCWEB_KVM) 311225b54dbaSEd Tanous { 31130e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3114002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 311525b54dbaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 311625b54dbaSEd Tanous 4; 3117613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3118613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 311925b54dbaSEd Tanous } 312013451e39SWilly Tu 3121bd79bce8SPatrick Williams getMainChassisId( 3122bd79bce8SPatrick Williams asyncResp, [](const std::string& chassisId, 31238d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3124b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3125b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3126bd79bce8SPatrick Williams chassis["@odata.id"] = 3127bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Chassis/{}", chassisId); 3128002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3129c5d03ff4SJennifer Lee }); 3130a3002228SAppaRao Puli 313159a17e4fSGeorge Liu getSystemLocationIndicatorActive(asyncResp); 31329f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3133a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 313451bd2d8aSGunnar Mills getComputerSystem(asyncResp); 31356c34de48SEd Tanous getHostState(asyncResp); 3136491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3137978b8803SAndrew Geissler getBootProgress(asyncResp); 3138b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 313970c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 314070c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 314151709ffdSYong Li getHostWatchdogTimer(asyncResp); 3142c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 31439dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3144797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3145c0557e1aSGunnar Mills getLastResetTime(asyncResp); 314625b54dbaSEd Tanous if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE) 314725b54dbaSEd Tanous { 3148a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 314925b54dbaSEd Tanous } 31501981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 31513a2d0424SChris Cain getPowerMode(asyncResp); 315237bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3153c1e219d5SEd Tanous } 3154550a6bf8SJiaqing Zhao 3155c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3156c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 315722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3158c1e219d5SEd Tanous const std::string& systemName) 3159c1e219d5SEd Tanous { 31603ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 316145ca1b86SEd Tanous { 316245ca1b86SEd Tanous return; 316345ca1b86SEd Tanous } 316425b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 31657f3e84a1SEd Tanous { 31667f3e84a1SEd Tanous // Option currently returns no systems. TBD 31677f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31687f3e84a1SEd Tanous systemName); 31697f3e84a1SEd Tanous return; 31707f3e84a1SEd Tanous } 3171253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 317222d268cbSEd Tanous { 317322d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 317422d268cbSEd Tanous systemName); 317522d268cbSEd Tanous return; 317622d268cbSEd Tanous } 317722d268cbSEd Tanous 3178dd60b9edSEd Tanous asyncResp->res.addHeader( 3179dd60b9edSEd Tanous boost::beast::http::field::link, 3180dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3181dd60b9edSEd Tanous 31829f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3183cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 318498e386ecSGunnar Mills std::optional<std::string> assetTag; 3185c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 31863a2d0424SChris Cain std::optional<std::string> powerMode; 3187550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3188550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3189550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3190550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3191550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3192550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3193797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3194550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 31959dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3196550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3197550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3198550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3199550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3200550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3201550a6bf8SJiaqing Zhao 3202550a6bf8SJiaqing Zhao // clang-format off 320315ed6780SWilly Tu if (!json_util::readJsonPatch( 3204550a6bf8SJiaqing Zhao req, asyncResp->res, 3205550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 32067e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3207550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3208550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3209550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3210550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3211550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3212550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3213550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3214550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3215550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3216797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3217550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 32189dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3219550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3220550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3221550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3222550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3223550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 32246617338dSEd Tanous { 32256617338dSEd Tanous return; 32266617338dSEd Tanous } 3227550a6bf8SJiaqing Zhao // clang-format on 3228491d8ee7SSantosh Puranik 32298d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3230c45f0082SYong Li 323198e386ecSGunnar Mills if (assetTag) 323298e386ecSGunnar Mills { 323398e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 323498e386ecSGunnar Mills } 323598e386ecSGunnar Mills 3236550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3237c45f0082SYong Li { 3238f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3239c45f0082SYong Li } 3240c45f0082SYong Li 3241cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 324269f35306SGunnar Mills { 3243002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3244491d8ee7SSantosh Puranik } 3245550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 324669f35306SGunnar Mills { 3247550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 324869f35306SGunnar Mills } 3249ac7e1e0bSAli Ahmed 3250797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3251797d5daeSCorey Hardesty { 3252797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3253797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3254797d5daeSCorey Hardesty } 3255797d5daeSCorey Hardesty 3256550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3257ac7e1e0bSAli Ahmed { 3258c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 325969f35306SGunnar Mills } 3260265c1602SJohnathan Mantey 32619dcfe8c1SAlbert Zhang if (stopBootOnFault) 32629dcfe8c1SAlbert Zhang { 32639dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 32649dcfe8c1SAlbert Zhang } 32659dcfe8c1SAlbert Zhang 32669f8bfa7cSGunnar Mills if (locationIndicatorActive) 32679f8bfa7cSGunnar Mills { 326859a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 32699f8bfa7cSGunnar Mills } 32709f8bfa7cSGunnar Mills 32717e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32727e860f15SJohn Edward Broadbent // passed 32739712f8acSEd Tanous if (indicatorLed) 32746617338dSEd Tanous { 3275f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3276002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3277d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3278d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32796617338dSEd Tanous } 3280c6a620f2SGeorge Liu 3281c6a620f2SGeorge Liu if (powerRestorePolicy) 3282c6a620f2SGeorge Liu { 32834e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3284c6a620f2SGeorge Liu } 32853a2d0424SChris Cain 32863a2d0424SChris Cain if (powerMode) 32873a2d0424SChris Cain { 32883a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32893a2d0424SChris Cain } 329037bbf98cSChris Cain 3291c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 329237bbf98cSChris Cain { 3293002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3294002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 329537bbf98cSChris Cain } 3296c1e219d5SEd Tanous } 32971cb1a9e6SAppaRao Puli 329838c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3299dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 33007f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3301c1e219d5SEd Tanous const std::string& /*systemName*/) 3302dd60b9edSEd Tanous { 3303dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3304dd60b9edSEd Tanous { 3305dd60b9edSEd Tanous return; 3306dd60b9edSEd Tanous } 3307dd60b9edSEd Tanous asyncResp->res.addHeader( 3308dd60b9edSEd Tanous boost::beast::http::field::link, 3309dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3310dd60b9edSEd Tanous } 331133e1f122SAndrew Geissler 331233e1f122SAndrew Geissler /** 331333e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 331433e1f122SAndrew Geissler * 331533e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 331633e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 331733e1f122SAndrew Geissler * 3318efff2b5dSManojkiran Eda * @return Emplaces corresponding Redfish translated value(s) in 331933e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 332033e1f122SAndrew Geissler * allowableValues. 332133e1f122SAndrew Geissler */ 332233e1f122SAndrew Geissler inline void 332333e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran, 332433e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 332533e1f122SAndrew Geissler { 332633e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 332733e1f122SAndrew Geissler { 332833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 332933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 333033e1f122SAndrew Geissler } 333133e1f122SAndrew Geissler else if (dbusAllowedHostTran == 333233e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 333333e1f122SAndrew Geissler { 333433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 333533e1f122SAndrew Geissler } 333633e1f122SAndrew Geissler else if (dbusAllowedHostTran == 333733e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 333833e1f122SAndrew Geissler { 333933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 334033e1f122SAndrew Geissler } 334133e1f122SAndrew Geissler else if (dbusAllowedHostTran == 334233e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 334333e1f122SAndrew Geissler { 334433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 334533e1f122SAndrew Geissler } 334633e1f122SAndrew Geissler else 334733e1f122SAndrew Geissler { 334833e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 334933e1f122SAndrew Geissler } 335033e1f122SAndrew Geissler } 335133e1f122SAndrew Geissler 335233e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 335333e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 335433e1f122SAndrew Geissler const boost::system::error_code& ec, 335533e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 335633e1f122SAndrew Geissler { 335733e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 335833e1f122SAndrew Geissler 335933e1f122SAndrew Geissler // Supported on all systems currently 336033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 336133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 336233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 336333e1f122SAndrew Geissler 336433e1f122SAndrew Geissler if (ec) 336533e1f122SAndrew Geissler { 3366e715d14bSEd Tanous if ((ec.value() == 3367e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3368e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 336933e1f122SAndrew Geissler { 337033e1f122SAndrew Geissler // Property not implemented so just return defaults 337133e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 337233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 337333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 337433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 337533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 337633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 337733e1f122SAndrew Geissler } 337833e1f122SAndrew Geissler else 337933e1f122SAndrew Geissler { 338033e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 338133e1f122SAndrew Geissler messages::internalError(asyncResp->res); 338233e1f122SAndrew Geissler return; 338333e1f122SAndrew Geissler } 338433e1f122SAndrew Geissler } 338533e1f122SAndrew Geissler else 338633e1f122SAndrew Geissler { 338733e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 338833e1f122SAndrew Geissler { 338933e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 339033e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 339133e1f122SAndrew Geissler } 339233e1f122SAndrew Geissler } 339333e1f122SAndrew Geissler 339433e1f122SAndrew Geissler nlohmann::json::object_t parameter; 339533e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 339633e1f122SAndrew Geissler parameter["Required"] = true; 3397539d8c6bSEd Tanous parameter["DataType"] = action_info::ParameterTypes::String; 339833e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 339933e1f122SAndrew Geissler nlohmann::json::array_t parameters; 340033e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 340133e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 340233e1f122SAndrew Geissler } 340333e1f122SAndrew Geissler 3404c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3405c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 340622d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3407c1e219d5SEd Tanous const std::string& systemName) 3408c1e219d5SEd Tanous { 34093ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 341045ca1b86SEd Tanous { 341145ca1b86SEd Tanous return; 341245ca1b86SEd Tanous } 341325b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 34147f3e84a1SEd Tanous { 34157f3e84a1SEd Tanous // Option currently returns no systems. TBD 34167f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 34177f3e84a1SEd Tanous systemName); 34187f3e84a1SEd Tanous return; 34197f3e84a1SEd Tanous } 3420746b56f3SAsmitha Karunanithi 342168896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 342268896206SGunnar Mills { 3423746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3424746b56f3SAsmitha Karunanithi { 3425746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3426746b56f3SAsmitha Karunanithi return; 3427746b56f3SAsmitha Karunanithi } 342868896206SGunnar Mills } 3429746b56f3SAsmitha Karunanithi 3430253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 343122d268cbSEd Tanous { 343222d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 343322d268cbSEd Tanous systemName); 343422d268cbSEd Tanous return; 343522d268cbSEd Tanous } 343622d268cbSEd Tanous 3437dd60b9edSEd Tanous asyncResp->res.addHeader( 3438dd60b9edSEd Tanous boost::beast::http::field::link, 3439dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34401476687dSEd Tanous 34411476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 3442253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3443253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3444c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34451476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34461476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34473215e700SNan Zhou 344833e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 344933e1f122SAndrew Geissler sdbusplus::asio::getProperty<std::vector<std::string>>( 345033e1f122SAndrew Geissler *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 345133e1f122SAndrew Geissler "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 345233e1f122SAndrew Geissler "AllowedHostTransitions", 345333e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 345433e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 3455bd79bce8SPatrick Williams afterGetAllowedHostTransitions(asyncResp, ec, 3456bd79bce8SPatrick Williams allowedHostTransitions); 345733e1f122SAndrew Geissler }); 3458c1e219d5SEd Tanous } 3459c1e219d5SEd Tanous /** 3460c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3461c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3462c1e219d5SEd Tanous */ 3463100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3464c1e219d5SEd Tanous { 3465100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3466100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3467100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3468100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3469100afe56SEd Tanous 3470100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3471100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3472100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3473100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3474100afe56SEd Tanous 3475100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3476100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3477100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3478100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3479100afe56SEd Tanous 3480100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3481100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3482100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3483100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3484100afe56SEd Tanous 3485100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3486100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3487100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3488100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3489100afe56SEd Tanous 3490100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3491100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3492100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3493100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3494100afe56SEd Tanous 3495c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3496c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3497c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3498c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3499c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3500c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3501c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3502c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 35031cb1a9e6SAppaRao Puli } 3504c5b2abe0SLewanczyk, Dawid } // namespace redfish 3505