1c5b2abe0SLewanczyk, Dawid /* 26be832e2SEd Tanous Copyright (c) 2018 Intel Corporation 36be832e2SEd Tanous 46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License"); 56be832e2SEd Tanous you may not use this file except in compliance with the License. 66be832e2SEd Tanous You may obtain a copy of the License at 76be832e2SEd Tanous 86be832e2SEd Tanous http://www.apache.org/licenses/LICENSE-2.0 96be832e2SEd Tanous 106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software 116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS, 126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136be832e2SEd Tanous See the License for the specific language governing permissions and 146be832e2SEd Tanous 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 } 2875dd7090e6SGunnar Mills 2876dd7090e6SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 2877dd7090e6SGunnar Mills { 2878dd7090e6SGunnar Mills if (systemName == "hypervisor") 2879dd7090e6SGunnar Mills { 2880dd7090e6SGunnar Mills handleHypervisorSystemResetPost(req, asyncResp); 2881dd7090e6SGunnar Mills return; 2882dd7090e6SGunnar Mills } 2883dd7090e6SGunnar Mills } 2884dd7090e6SGunnar 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 3202*afc474aeSMyung Bae if (!json_util::readJsonPatch( // 3203*afc474aeSMyung Bae req, asyncResp->res, // 3204*afc474aeSMyung Bae "AssetTag", assetTag, // 3205*afc474aeSMyung Bae "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, // 3206*afc474aeSMyung Bae "Boot/AutomaticRetryConfig", bootAutomaticRetry, // 3207*afc474aeSMyung Bae "Boot/BootSourceOverrideEnabled", bootEnable, // 3208*afc474aeSMyung Bae "Boot/BootSourceOverrideMode", bootType, // 3209*afc474aeSMyung Bae "Boot/BootSourceOverrideTarget", bootSource, // 3210*afc474aeSMyung Bae "Boot/StopBootOnFault", stopBootOnFault, // 3211*afc474aeSMyung Bae "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, // 3212*afc474aeSMyung Bae "HostWatchdogTimer/FunctionEnabled", wdtEnable, // 3213*afc474aeSMyung Bae "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, // 3214*afc474aeSMyung Bae "IdlePowerSaver/Enabled", ipsEnable, // 3215*afc474aeSMyung Bae "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, // 3216*afc474aeSMyung Bae "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, // 3217*afc474aeSMyung Bae "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, // 3218*afc474aeSMyung Bae "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, // 3219*afc474aeSMyung Bae "IndicatorLED", indicatorLed, // 3220*afc474aeSMyung Bae "LocationIndicatorActive", locationIndicatorActive, // 3221*afc474aeSMyung Bae "PowerMode", powerMode, // 3222*afc474aeSMyung Bae "PowerRestorePolicy", powerRestorePolicy // 3223*afc474aeSMyung Bae )) 32246617338dSEd Tanous { 32256617338dSEd Tanous return; 32266617338dSEd Tanous } 3227491d8ee7SSantosh Puranik 32288d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3229c45f0082SYong Li 323098e386ecSGunnar Mills if (assetTag) 323198e386ecSGunnar Mills { 323298e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 323398e386ecSGunnar Mills } 323498e386ecSGunnar Mills 3235550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3236c45f0082SYong Li { 3237f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3238c45f0082SYong Li } 3239c45f0082SYong Li 3240cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 324169f35306SGunnar Mills { 3242002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3243491d8ee7SSantosh Puranik } 3244550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 324569f35306SGunnar Mills { 3246550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 324769f35306SGunnar Mills } 3248ac7e1e0bSAli Ahmed 3249797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3250797d5daeSCorey Hardesty { 3251797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3252797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3253797d5daeSCorey Hardesty } 3254797d5daeSCorey Hardesty 3255550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3256ac7e1e0bSAli Ahmed { 3257c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 325869f35306SGunnar Mills } 3259265c1602SJohnathan Mantey 32609dcfe8c1SAlbert Zhang if (stopBootOnFault) 32619dcfe8c1SAlbert Zhang { 32629dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 32639dcfe8c1SAlbert Zhang } 32649dcfe8c1SAlbert Zhang 32659f8bfa7cSGunnar Mills if (locationIndicatorActive) 32669f8bfa7cSGunnar Mills { 326759a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 32689f8bfa7cSGunnar Mills } 32699f8bfa7cSGunnar Mills 32707e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32717e860f15SJohn Edward Broadbent // passed 32729712f8acSEd Tanous if (indicatorLed) 32736617338dSEd Tanous { 3274f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3275002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3276d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3277d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32786617338dSEd Tanous } 3279c6a620f2SGeorge Liu 3280c6a620f2SGeorge Liu if (powerRestorePolicy) 3281c6a620f2SGeorge Liu { 32824e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3283c6a620f2SGeorge Liu } 32843a2d0424SChris Cain 32853a2d0424SChris Cain if (powerMode) 32863a2d0424SChris Cain { 32873a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32883a2d0424SChris Cain } 328937bbf98cSChris Cain 3290c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 329137bbf98cSChris Cain { 3292002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3293002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 329437bbf98cSChris Cain } 3295c1e219d5SEd Tanous } 32961cb1a9e6SAppaRao Puli 329738c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3298dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 32997f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3300c1e219d5SEd Tanous const std::string& /*systemName*/) 3301dd60b9edSEd Tanous { 3302dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3303dd60b9edSEd Tanous { 3304dd60b9edSEd Tanous return; 3305dd60b9edSEd Tanous } 3306dd60b9edSEd Tanous asyncResp->res.addHeader( 3307dd60b9edSEd Tanous boost::beast::http::field::link, 3308dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3309dd60b9edSEd Tanous } 331033e1f122SAndrew Geissler 331133e1f122SAndrew Geissler /** 331233e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 331333e1f122SAndrew Geissler * 331433e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 331533e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 331633e1f122SAndrew Geissler * 3317efff2b5dSManojkiran Eda * @return Emplaces corresponding Redfish translated value(s) in 331833e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 331933e1f122SAndrew Geissler * allowableValues. 332033e1f122SAndrew Geissler */ 332133e1f122SAndrew Geissler inline void 332233e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran, 332333e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 332433e1f122SAndrew Geissler { 332533e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 332633e1f122SAndrew Geissler { 332733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 332833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 332933e1f122SAndrew Geissler } 333033e1f122SAndrew Geissler else if (dbusAllowedHostTran == 333133e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 333233e1f122SAndrew Geissler { 333333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 333433e1f122SAndrew Geissler } 333533e1f122SAndrew Geissler else if (dbusAllowedHostTran == 333633e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 333733e1f122SAndrew Geissler { 333833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 333933e1f122SAndrew Geissler } 334033e1f122SAndrew Geissler else if (dbusAllowedHostTran == 334133e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 334233e1f122SAndrew Geissler { 334333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 334433e1f122SAndrew Geissler } 334533e1f122SAndrew Geissler else 334633e1f122SAndrew Geissler { 334733e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 334833e1f122SAndrew Geissler } 334933e1f122SAndrew Geissler } 335033e1f122SAndrew Geissler 335133e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 335233e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 335333e1f122SAndrew Geissler const boost::system::error_code& ec, 335433e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 335533e1f122SAndrew Geissler { 335633e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 335733e1f122SAndrew Geissler 335833e1f122SAndrew Geissler // Supported on all systems currently 335933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 336033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 336133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 336233e1f122SAndrew Geissler 336333e1f122SAndrew Geissler if (ec) 336433e1f122SAndrew Geissler { 3365e715d14bSEd Tanous if ((ec.value() == 3366e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3367e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 336833e1f122SAndrew Geissler { 336933e1f122SAndrew Geissler // Property not implemented so just return defaults 337033e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 337133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 337233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 337333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 337433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 337533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 337633e1f122SAndrew Geissler } 337733e1f122SAndrew Geissler else 337833e1f122SAndrew Geissler { 337933e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 338033e1f122SAndrew Geissler messages::internalError(asyncResp->res); 338133e1f122SAndrew Geissler return; 338233e1f122SAndrew Geissler } 338333e1f122SAndrew Geissler } 338433e1f122SAndrew Geissler else 338533e1f122SAndrew Geissler { 338633e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 338733e1f122SAndrew Geissler { 338833e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 338933e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 339033e1f122SAndrew Geissler } 339133e1f122SAndrew Geissler } 339233e1f122SAndrew Geissler 339333e1f122SAndrew Geissler nlohmann::json::object_t parameter; 339433e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 339533e1f122SAndrew Geissler parameter["Required"] = true; 3396539d8c6bSEd Tanous parameter["DataType"] = action_info::ParameterTypes::String; 339733e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 339833e1f122SAndrew Geissler nlohmann::json::array_t parameters; 339933e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 340033e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 340133e1f122SAndrew Geissler } 340233e1f122SAndrew Geissler 3403c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3404c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 340522d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3406c1e219d5SEd Tanous const std::string& systemName) 3407c1e219d5SEd Tanous { 34083ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 340945ca1b86SEd Tanous { 341045ca1b86SEd Tanous return; 341145ca1b86SEd Tanous } 341225b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 34137f3e84a1SEd Tanous { 34147f3e84a1SEd Tanous // Option currently returns no systems. TBD 34157f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 34167f3e84a1SEd Tanous systemName); 34177f3e84a1SEd Tanous return; 34187f3e84a1SEd Tanous } 3419746b56f3SAsmitha Karunanithi 342068896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 342168896206SGunnar Mills { 3422746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3423746b56f3SAsmitha Karunanithi { 3424746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3425746b56f3SAsmitha Karunanithi return; 3426746b56f3SAsmitha Karunanithi } 342768896206SGunnar Mills } 3428746b56f3SAsmitha Karunanithi 3429253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 343022d268cbSEd Tanous { 343122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 343222d268cbSEd Tanous systemName); 343322d268cbSEd Tanous return; 343422d268cbSEd Tanous } 343522d268cbSEd Tanous 3436dd60b9edSEd Tanous asyncResp->res.addHeader( 3437dd60b9edSEd Tanous boost::beast::http::field::link, 3438dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34391476687dSEd Tanous 34401476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 3441253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3442253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3443c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34441476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34451476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34463215e700SNan Zhou 344733e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 344833e1f122SAndrew Geissler sdbusplus::asio::getProperty<std::vector<std::string>>( 344933e1f122SAndrew Geissler *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 345033e1f122SAndrew Geissler "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 345133e1f122SAndrew Geissler "AllowedHostTransitions", 345233e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 345333e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 3454bd79bce8SPatrick Williams afterGetAllowedHostTransitions(asyncResp, ec, 3455bd79bce8SPatrick Williams allowedHostTransitions); 345633e1f122SAndrew Geissler }); 3457c1e219d5SEd Tanous } 3458c1e219d5SEd Tanous /** 3459c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3460c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3461c1e219d5SEd Tanous */ 3462100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3463c1e219d5SEd Tanous { 3464100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3465100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3466100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3467100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3468100afe56SEd Tanous 3469100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3470100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3471100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3472100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3473100afe56SEd Tanous 3474100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3475100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3476100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3477100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3478100afe56SEd Tanous 3479100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3480100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3481100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3482100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3483100afe56SEd Tanous 3484100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3485100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3486100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3487100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3488100afe56SEd Tanous 3489100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3490100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3491100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3492100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3493100afe56SEd Tanous 3494c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3495c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3496c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3497c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3498c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3499c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3500c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3501c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 35021cb1a9e6SAppaRao Puli } 3503c5b2abe0SLewanczyk, Dawid } // namespace redfish 3504