1c5b2abe0SLewanczyk, Dawid /* 2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation 3c5b2abe0SLewanczyk, Dawid // 4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License"); 5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License. 6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at 7c5b2abe0SLewanczyk, Dawid // 8c5b2abe0SLewanczyk, Dawid // http://www.apache.org/licenses/LICENSE-2.0 9c5b2abe0SLewanczyk, Dawid // 10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software 11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS, 12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and 14c5b2abe0SLewanczyk, Dawid // limitations under the License. 15c5b2abe0SLewanczyk, Dawid */ 16c5b2abe0SLewanczyk, Dawid #pragma once 17c5b2abe0SLewanczyk, Dawid 1813451e39SWilly Tu #include "bmcweb_config.h" 1913451e39SWilly Tu 203ccb3adbSEd Tanous #include "app.hpp" 211e1e598dSJonathan Doman #include "dbus_singleton.hpp" 227a1dbc48SGeorge Liu #include "dbus_utility.hpp" 238d69c668SEd Tanous #include "generated/enums/computer_system.hpp" 2433e1f122SAndrew Geissler #include "generated/enums/resource.hpp" 25b49ac873SJames Feist #include "health.hpp" 26746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 271c8fba97SJames Feist #include "led.hpp" 28f4c99e70SEd Tanous #include "query.hpp" 29c5d03ff4SJennifer Lee #include "redfish_util.hpp" 303ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 313ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 323ccb3adbSEd Tanous #include "utils/json_utils.hpp" 33472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 343ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 352b82937eSEd Tanous #include "utils/time_utils.hpp" 36c5d03ff4SJennifer Lee 37fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 389712f8acSEd Tanous #include <boost/container/flat_map.hpp> 39e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 4033e1f122SAndrew Geissler #include <boost/system/linux_error.hpp> 41ef4c65b7SEd Tanous #include <boost/url/format.hpp> 421e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 43fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 44bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 451214b7e7SGunnar Mills 467a1dbc48SGeorge Liu #include <array> 4733e1f122SAndrew Geissler #include <memory> 486b9ac4f2SChris Cain #include <string> 497a1dbc48SGeorge Liu #include <string_view> 50abf2add6SEd Tanous #include <variant> 516b9ac4f2SChris Cain #include <vector> 52c5b2abe0SLewanczyk, Dawid 531abe55efSEd Tanous namespace redfish 541abe55efSEd Tanous { 55c5b2abe0SLewanczyk, Dawid 565c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 575c3e9272SAbhishek Patel protocolToDBusForSystems{ 585c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 595c3e9272SAbhishek Patel 609d3ae10eSAlpana Kumari /** 619d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 629d3ae10eSAlpana Kumari * 63ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 649d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 659d3ae10eSAlpana Kumari * 669d3ae10eSAlpana Kumari * @return None. 679d3ae10eSAlpana Kumari */ 688d1b46d7Szhanghch05 inline void 69ac106bf6SEd Tanous updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 701e1e598dSJonathan Doman bool isDimmFunctional) 719d3ae10eSAlpana Kumari { 7262598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 739d3ae10eSAlpana Kumari 749d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 759d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 769d3ae10eSAlpana Kumari // ENABLED. 7702cad96eSEd Tanous const nlohmann::json& prevMemSummary = 78ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 799d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 809d3ae10eSAlpana Kumari { 81e05aec50SEd Tanous if (isDimmFunctional) 829d3ae10eSAlpana Kumari { 83ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 849d3ae10eSAlpana Kumari "Enabled"; 859d3ae10eSAlpana Kumari } 869d3ae10eSAlpana Kumari } 879d3ae10eSAlpana Kumari } 889d3ae10eSAlpana Kumari 8957e8c9beSAlpana Kumari /* 9057e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 9157e8c9beSAlpana Kumari * CPU Functional State 9257e8c9beSAlpana Kumari * 93ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 9457e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9557e8c9beSAlpana Kumari * 9657e8c9beSAlpana Kumari * @return None. 9757e8c9beSAlpana Kumari */ 98ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 99ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 10057e8c9beSAlpana Kumari { 10162598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 10257e8c9beSAlpana Kumari 10302cad96eSEd Tanous const nlohmann::json& prevProcState = 104ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10557e8c9beSAlpana Kumari 10657e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10757e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10857e8c9beSAlpana Kumari // Functional. 10957e8c9beSAlpana Kumari if (prevProcState == "Disabled") 11057e8c9beSAlpana Kumari { 111e05aec50SEd Tanous if (isCpuFunctional) 11257e8c9beSAlpana Kumari { 113ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 11457e8c9beSAlpana Kumari "Enabled"; 11557e8c9beSAlpana Kumari } 11657e8c9beSAlpana Kumari } 11757e8c9beSAlpana Kumari } 11857e8c9beSAlpana Kumari 119cf0e004cSNinad Palsule /* 120cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 121cf0e004cSNinad Palsule * 122ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 123cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 124cf0e004cSNinad Palsule * 125cf0e004cSNinad Palsule * @return None. 126cf0e004cSNinad Palsule */ 127cf0e004cSNinad Palsule inline void 128ac106bf6SEd Tanous modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 129cf0e004cSNinad Palsule 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 } 304*51bd2d8aSGunnar 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 406a974c132SLakshmi Yadlapati inline void 407a974c132SLakshmi Yadlapati afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 408a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 409a974c132SLakshmi Yadlapati const std::string& value) 410a974c132SLakshmi Yadlapati { 411a974c132SLakshmi Yadlapati if (ec) 412a974c132SLakshmi Yadlapati { 413a974c132SLakshmi Yadlapati // doesn't have to include this 414a974c132SLakshmi Yadlapati // interface 415a974c132SLakshmi Yadlapati return; 416a974c132SLakshmi Yadlapati } 417a974c132SLakshmi Yadlapati 418a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["AssetTag"] = value; 419a974c132SLakshmi Yadlapati } 420a974c132SLakshmi Yadlapati 421a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree( 422a974c132SLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 423a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 424a974c132SLakshmi Yadlapati const dbus::utility::MapperGetSubTreeResponse& subtree) 425a974c132SLakshmi Yadlapati { 4261abe55efSEd Tanous if (ec) 4271abe55efSEd Tanous { 428b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 429ac106bf6SEd Tanous messages::internalError(asyncResp->res); 430c5b2abe0SLewanczyk, Dawid return; 431c5b2abe0SLewanczyk, Dawid } 432c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 433002d39b4SEd Tanous for (const std::pair< 434002d39b4SEd Tanous std::string, 435002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 4361214b7e7SGunnar Mills object : subtree) 4371abe55efSEd Tanous { 438c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 43962598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 440002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 4411214b7e7SGunnar Mills connectionNames = object.second; 44226f6976fSEd Tanous if (connectionNames.empty()) 4431abe55efSEd Tanous { 444c5b2abe0SLewanczyk, Dawid continue; 445c5b2abe0SLewanczyk, Dawid } 446029573d4SEd Tanous 4476c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4486c34de48SEd Tanous // BiosVer 44904a258f4SEd Tanous for (const auto& connection : connectionNames) 4501abe55efSEd Tanous { 45104a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4521abe55efSEd Tanous { 453a974c132SLakshmi Yadlapati if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") 4541abe55efSEd Tanous { 45562598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 4569d3ae10eSAlpana Kumari 457ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4585fd0aafbSNinad Palsule } 45904a258f4SEd Tanous else if (interfaceName == 46004a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4611abe55efSEd Tanous { 46262598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 46357e8c9beSAlpana Kumari 464ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4655fd0aafbSNinad Palsule } 466002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4671abe55efSEd Tanous { 46862598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 469bc1d29deSKrzysztof Grobelny 470bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 471a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 472a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 473ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 474b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4751214b7e7SGunnar Mills properties) { 476a974c132SLakshmi Yadlapati afterGetUUID(asyncResp, ec3, properties); 477bc1d29deSKrzysztof Grobelny }); 478c5b2abe0SLewanczyk, Dawid } 479029573d4SEd Tanous else if (interfaceName == 480029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4811abe55efSEd Tanous { 482bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 483a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 484bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 485a974c132SLakshmi Yadlapati [asyncResp](const boost::system::error_code& ec3, 486b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 487a974c132SLakshmi Yadlapati properties) { 488a974c132SLakshmi Yadlapati afterGetInventory(asyncResp, ec3, properties); 489bc1d29deSKrzysztof Grobelny }); 490e4a4b9a9SJames Feist 4911e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 492a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 4931e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 4941e1e598dSJonathan Doman "AssetTag", 4951e1e598dSJonathan Doman "AssetTag", 496a974c132SLakshmi Yadlapati std::bind_front(afterGetAssetTag, asyncResp)); 497a974c132SLakshmi Yadlapati } 498a974c132SLakshmi Yadlapati } 499a974c132SLakshmi Yadlapati } 500a974c132SLakshmi Yadlapati } 501a974c132SLakshmi Yadlapati } 502a974c132SLakshmi Yadlapati 503a974c132SLakshmi Yadlapati /* 504a974c132SLakshmi Yadlapati * @brief Retrieves computer system properties over dbus 505a974c132SLakshmi Yadlapati * 506a974c132SLakshmi Yadlapati * @param[in] asyncResp Shared pointer for completing asynchronous calls 507a974c132SLakshmi Yadlapati * 508a974c132SLakshmi Yadlapati * @return None. 509a974c132SLakshmi Yadlapati */ 510a974c132SLakshmi Yadlapati inline void 511*51bd2d8aSGunnar Mills getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 512e4a4b9a9SJames Feist { 513a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get available system components."); 514a974c132SLakshmi Yadlapati constexpr std::array<std::string_view, 5> interfaces = { 515a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 516a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Cpu", 517a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Dimm", 518a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.System", 519a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 520a974c132SLakshmi Yadlapati }; 521a974c132SLakshmi Yadlapati dbus::utility::getSubTree( 522a974c132SLakshmi Yadlapati "/xyz/openbmc_project/inventory", 0, interfaces, 523*51bd2d8aSGunnar Mills std::bind_front(afterSystemGetSubTree, asyncResp)); 524c5b2abe0SLewanczyk, Dawid } 525c5b2abe0SLewanczyk, Dawid 526c5b2abe0SLewanczyk, Dawid /** 527c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 528c5b2abe0SLewanczyk, Dawid * 529ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 530c5b2abe0SLewanczyk, Dawid * 531c5b2abe0SLewanczyk, Dawid * @return None. 532c5b2abe0SLewanczyk, Dawid */ 533ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5341abe55efSEd Tanous { 53562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 5361e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5371e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 5381e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 5391e1e598dSJonathan Doman "CurrentHostState", 540ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 5411e1e598dSJonathan Doman const std::string& hostState) { 5421abe55efSEd Tanous if (ec) 5431abe55efSEd Tanous { 54422228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 54522228c28SAndrew Geissler { 54622228c28SAndrew Geissler // Service not available, no error, just don't return 54722228c28SAndrew Geissler // host state info 54862598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 54922228c28SAndrew Geissler return; 55022228c28SAndrew Geissler } 55162598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 552ac106bf6SEd Tanous messages::internalError(asyncResp->res); 553c5b2abe0SLewanczyk, Dawid return; 554c5b2abe0SLewanczyk, Dawid } 5556617338dSEd Tanous 55662598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 557c5b2abe0SLewanczyk, Dawid // Verify Host State 5581e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5591abe55efSEd Tanous { 560ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 561ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 5621abe55efSEd Tanous } 5631e1e598dSJonathan Doman else if (hostState == 5640fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5658c888608SGunnar Mills { 566ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 567ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 5688c888608SGunnar Mills } 5691e1e598dSJonathan Doman else if (hostState == 5700fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 57183935af9SAndrew Geissler { 572ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 573ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 57483935af9SAndrew Geissler } 5750fda0f12SGeorge Liu else if ( 5761e1e598dSJonathan Doman hostState == 5770fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5781a2a1437SAndrew Geissler { 579ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 580ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 5811a2a1437SAndrew Geissler } 582002d39b4SEd Tanous else if (hostState == 5830fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5841a2a1437SAndrew Geissler { 585ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 586ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 5871a2a1437SAndrew Geissler } 5881abe55efSEd Tanous else 5891abe55efSEd Tanous { 590ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 591ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 592c5b2abe0SLewanczyk, Dawid } 5931e1e598dSJonathan Doman }); 594c5b2abe0SLewanczyk, Dawid } 595c5b2abe0SLewanczyk, Dawid 596c5b2abe0SLewanczyk, Dawid /** 597786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 598491d8ee7SSantosh Puranik * 599491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 600491d8ee7SSantosh Puranik * 601491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 602491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 603491d8ee7SSantosh Puranik */ 60423a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 605491d8ee7SSantosh Puranik { 606491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 607491d8ee7SSantosh Puranik { 608491d8ee7SSantosh Puranik return "None"; 609491d8ee7SSantosh Puranik } 6103174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 611491d8ee7SSantosh Puranik { 612491d8ee7SSantosh Puranik return "Hdd"; 613491d8ee7SSantosh Puranik } 6143174e4dfSEd Tanous if (dbusSource == 615a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 616491d8ee7SSantosh Puranik { 617491d8ee7SSantosh Puranik return "Cd"; 618491d8ee7SSantosh Puranik } 6193174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 620491d8ee7SSantosh Puranik { 621491d8ee7SSantosh Puranik return "Pxe"; 622491d8ee7SSantosh Puranik } 6233174e4dfSEd Tanous if (dbusSource == 624944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6259f16b2c1SJennifer Lee { 6269f16b2c1SJennifer Lee return "Usb"; 6279f16b2c1SJennifer Lee } 628491d8ee7SSantosh Puranik return ""; 629491d8ee7SSantosh Puranik } 630491d8ee7SSantosh Puranik 631491d8ee7SSantosh Puranik /** 632cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 633cd9a4666SKonstantin Aladyshev * 634cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 635cd9a4666SKonstantin Aladyshev * 636cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 637cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 638cd9a4666SKonstantin Aladyshev */ 639cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 640cd9a4666SKonstantin Aladyshev { 641cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 642cd9a4666SKonstantin Aladyshev { 643cd9a4666SKonstantin Aladyshev return "Legacy"; 644cd9a4666SKonstantin Aladyshev } 645cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 646cd9a4666SKonstantin Aladyshev { 647cd9a4666SKonstantin Aladyshev return "UEFI"; 648cd9a4666SKonstantin Aladyshev } 649cd9a4666SKonstantin Aladyshev return ""; 650cd9a4666SKonstantin Aladyshev } 651cd9a4666SKonstantin Aladyshev 652cd9a4666SKonstantin Aladyshev /** 653786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 654491d8ee7SSantosh Puranik * 655491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 656491d8ee7SSantosh Puranik * 657491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 658491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 659491d8ee7SSantosh Puranik */ 66023a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 661491d8ee7SSantosh Puranik { 662491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 663491d8ee7SSantosh Puranik { 664491d8ee7SSantosh Puranik return "None"; 665491d8ee7SSantosh Puranik } 6663174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 667491d8ee7SSantosh Puranik { 668491d8ee7SSantosh Puranik return "Diags"; 669491d8ee7SSantosh Puranik } 6703174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 671491d8ee7SSantosh Puranik { 672491d8ee7SSantosh Puranik return "BiosSetup"; 673491d8ee7SSantosh Puranik } 674491d8ee7SSantosh Puranik return ""; 675491d8ee7SSantosh Puranik } 676491d8ee7SSantosh Puranik 677491d8ee7SSantosh Puranik /** 678e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 679e43914b3SAndrew Geissler * 680e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 681e43914b3SAndrew Geissler * 682e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 683e43914b3SAndrew Geissler * translation cannot be done, returns "None". 684e43914b3SAndrew Geissler */ 685e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 686e43914b3SAndrew Geissler { 687e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 688e43914b3SAndrew Geissler // enum 689e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 690e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 691e43914b3SAndrew Geissler "ProgressStages.Unspecified") 692e43914b3SAndrew Geissler { 693e43914b3SAndrew Geissler rfBpLastState = "None"; 694e43914b3SAndrew Geissler } 695e43914b3SAndrew Geissler else if (dbusBootProgress == 696e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 697e43914b3SAndrew Geissler "PrimaryProcInit") 698e43914b3SAndrew Geissler { 699e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 700e43914b3SAndrew Geissler } 701e43914b3SAndrew Geissler else if (dbusBootProgress == 702e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 703e43914b3SAndrew Geissler "BusInit") 704e43914b3SAndrew Geissler { 705e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 706e43914b3SAndrew Geissler } 707e43914b3SAndrew Geissler else if (dbusBootProgress == 708e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 709e43914b3SAndrew Geissler "MemoryInit") 710e43914b3SAndrew Geissler { 711e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 712e43914b3SAndrew Geissler } 713e43914b3SAndrew Geissler else if (dbusBootProgress == 714e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 715e43914b3SAndrew Geissler "SecondaryProcInit") 716e43914b3SAndrew Geissler { 717e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 718e43914b3SAndrew Geissler } 719e43914b3SAndrew Geissler else if (dbusBootProgress == 720e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 721e43914b3SAndrew Geissler "PCIInit") 722e43914b3SAndrew Geissler { 723e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 724e43914b3SAndrew Geissler } 725e43914b3SAndrew Geissler else if (dbusBootProgress == 726e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 727e43914b3SAndrew Geissler "SystemSetup") 728e43914b3SAndrew Geissler { 729e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 730e43914b3SAndrew Geissler } 731e43914b3SAndrew Geissler else if (dbusBootProgress == 732e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 733e43914b3SAndrew Geissler "SystemInitComplete") 734e43914b3SAndrew Geissler { 735e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 736e43914b3SAndrew Geissler } 737e43914b3SAndrew Geissler else if (dbusBootProgress == 738e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 739e43914b3SAndrew Geissler "OSStart") 740e43914b3SAndrew Geissler { 741e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 742e43914b3SAndrew Geissler } 743e43914b3SAndrew Geissler else if (dbusBootProgress == 744e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 745e43914b3SAndrew Geissler "OSRunning") 746e43914b3SAndrew Geissler { 747e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 748e43914b3SAndrew Geissler } 749e43914b3SAndrew Geissler else 750e43914b3SAndrew Geissler { 75162598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 752e43914b3SAndrew Geissler // Just return the default 753e43914b3SAndrew Geissler } 754e43914b3SAndrew Geissler return rfBpLastState; 755e43914b3SAndrew Geissler } 756e43914b3SAndrew Geissler 757e43914b3SAndrew Geissler /** 758786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 759491d8ee7SSantosh Puranik * 760491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 761944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 762944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 763491d8ee7SSantosh Puranik * 764944ffaf9SJohnathan Mantey * @return Integer error code. 765491d8ee7SSantosh Puranik */ 766ac106bf6SEd Tanous inline int 767ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 768ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 769ac106bf6SEd Tanous std::string& bootMode) 770491d8ee7SSantosh Puranik { 771c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 772c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 773944ffaf9SJohnathan Mantey 774491d8ee7SSantosh Puranik if (rfSource == "None") 775491d8ee7SSantosh Puranik { 776944ffaf9SJohnathan Mantey return 0; 777491d8ee7SSantosh Puranik } 7783174e4dfSEd Tanous if (rfSource == "Pxe") 779491d8ee7SSantosh Puranik { 780944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 781944ffaf9SJohnathan Mantey } 782944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 783944ffaf9SJohnathan Mantey { 784944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 785944ffaf9SJohnathan Mantey } 786944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 787944ffaf9SJohnathan Mantey { 788944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 789944ffaf9SJohnathan Mantey } 790944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 791944ffaf9SJohnathan Mantey { 792944ffaf9SJohnathan Mantey bootSource = 793944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 794944ffaf9SJohnathan Mantey } 795944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 796944ffaf9SJohnathan Mantey { 797944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 798491d8ee7SSantosh Puranik } 7999f16b2c1SJennifer Lee else if (rfSource == "Usb") 8009f16b2c1SJennifer Lee { 801944ffaf9SJohnathan Mantey bootSource = 802944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8039f16b2c1SJennifer Lee } 804491d8ee7SSantosh Puranik else 805491d8ee7SSantosh Puranik { 80662598e31SEd Tanous BMCWEB_LOG_DEBUG( 80762598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 80862598e31SEd Tanous bootSource); 809ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 810944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 811944ffaf9SJohnathan Mantey return -1; 812491d8ee7SSantosh Puranik } 813944ffaf9SJohnathan Mantey return 0; 814491d8ee7SSantosh Puranik } 8151981771bSAli Ahmed 816978b8803SAndrew Geissler /** 817978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 818978b8803SAndrew Geissler * 819ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 820978b8803SAndrew Geissler * 821978b8803SAndrew Geissler * @return None. 822978b8803SAndrew Geissler */ 823ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 824978b8803SAndrew Geissler { 8251e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8261e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8271e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8281e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 829ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8301e1e598dSJonathan Doman const std::string& bootProgressStr) { 831978b8803SAndrew Geissler if (ec) 832978b8803SAndrew Geissler { 833978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 834978b8803SAndrew Geissler // not found 835978b8803SAndrew Geissler return; 836978b8803SAndrew Geissler } 837978b8803SAndrew Geissler 83862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 839978b8803SAndrew Geissler 840ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 841e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8421e1e598dSJonathan Doman }); 843978b8803SAndrew Geissler } 844491d8ee7SSantosh Puranik 845491d8ee7SSantosh Puranik /** 846b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 847b6d5d45cSHieu Huynh * 848ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 849b6d5d45cSHieu Huynh * 850b6d5d45cSHieu Huynh * @return None. 851b6d5d45cSHieu Huynh */ 852b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 853ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 854b6d5d45cSHieu Huynh { 855b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 856b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 857b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 858b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 859ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 860b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 861b6d5d45cSHieu Huynh if (ec) 862b6d5d45cSHieu Huynh { 86362598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 864b6d5d45cSHieu Huynh return; 865b6d5d45cSHieu Huynh } 866b6d5d45cSHieu Huynh 867b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 868b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 869b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 870b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 871b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 872b6d5d45cSHieu Huynh 873b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 874ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 875b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 876b6d5d45cSHieu Huynh }); 877b6d5d45cSHieu Huynh } 878b6d5d45cSHieu Huynh 879b6d5d45cSHieu Huynh /** 880c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 881cd9a4666SKonstantin Aladyshev * 882ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 883cd9a4666SKonstantin Aladyshev * 884cd9a4666SKonstantin Aladyshev * @return None. 885cd9a4666SKonstantin Aladyshev */ 886cd9a4666SKonstantin Aladyshev 887ac106bf6SEd Tanous inline void 888ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 889cd9a4666SKonstantin Aladyshev { 8901e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8911e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 8921e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 8931e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 894ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8951e1e598dSJonathan Doman const std::string& bootType) { 896cd9a4666SKonstantin Aladyshev if (ec) 897cd9a4666SKonstantin Aladyshev { 898cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 899cd9a4666SKonstantin Aladyshev return; 900cd9a4666SKonstantin Aladyshev } 901cd9a4666SKonstantin Aladyshev 90262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 903cd9a4666SKonstantin Aladyshev 904ac106bf6SEd Tanous asyncResp->res 905ac106bf6SEd Tanous .jsonValue["Boot"] 906002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 907613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 908cd9a4666SKonstantin Aladyshev 9091e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 910cd9a4666SKonstantin Aladyshev if (rfType.empty()) 911cd9a4666SKonstantin Aladyshev { 912ac106bf6SEd Tanous messages::internalError(asyncResp->res); 913cd9a4666SKonstantin Aladyshev return; 914cd9a4666SKonstantin Aladyshev } 915cd9a4666SKonstantin Aladyshev 916ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9171e1e598dSJonathan Doman }); 918cd9a4666SKonstantin Aladyshev } 919cd9a4666SKonstantin Aladyshev 920cd9a4666SKonstantin Aladyshev /** 921c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 922491d8ee7SSantosh Puranik * 923ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 924491d8ee7SSantosh Puranik * 925491d8ee7SSantosh Puranik * @return None. 926491d8ee7SSantosh Puranik */ 927c21865c4SKonstantin Aladyshev 928ac106bf6SEd Tanous inline void 929ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 930491d8ee7SSantosh Puranik { 9311e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9321e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9331e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9341e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 935ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9361e1e598dSJonathan Doman const std::string& bootModeStr) { 937491d8ee7SSantosh Puranik if (ec) 938491d8ee7SSantosh Puranik { 939b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 940ac106bf6SEd Tanous messages::internalError(asyncResp->res); 941491d8ee7SSantosh Puranik return; 942491d8ee7SSantosh Puranik } 943491d8ee7SSantosh Puranik 94462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 945491d8ee7SSantosh Puranik 946ac106bf6SEd Tanous asyncResp->res 9470fda0f12SGeorge Liu .jsonValue["Boot"] 948002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 949002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 950491d8ee7SSantosh Puranik 9511e1e598dSJonathan Doman if (bootModeStr != 952491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 953491d8ee7SSantosh Puranik { 9541e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 955491d8ee7SSantosh Puranik if (!rfMode.empty()) 956491d8ee7SSantosh Puranik { 957ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 958491d8ee7SSantosh Puranik rfMode; 959491d8ee7SSantosh Puranik } 960491d8ee7SSantosh Puranik } 9611e1e598dSJonathan Doman }); 962491d8ee7SSantosh Puranik } 963491d8ee7SSantosh Puranik 964491d8ee7SSantosh Puranik /** 965c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 966491d8ee7SSantosh Puranik * 967ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 968491d8ee7SSantosh Puranik * 969491d8ee7SSantosh Puranik * @return None. 970491d8ee7SSantosh Puranik */ 971c21865c4SKonstantin Aladyshev 972c21865c4SKonstantin Aladyshev inline void 973ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 974491d8ee7SSantosh Puranik { 9751e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9761e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9771e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9781e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 979ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9801e1e598dSJonathan Doman const std::string& bootSourceStr) { 981491d8ee7SSantosh Puranik if (ec) 982491d8ee7SSantosh Puranik { 9835ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 9845ef735c8SNan Zhou { 9855ef735c8SNan Zhou return; 9865ef735c8SNan Zhou } 987b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 988ac106bf6SEd Tanous messages::internalError(asyncResp->res); 989491d8ee7SSantosh Puranik return; 990491d8ee7SSantosh Puranik } 991491d8ee7SSantosh Puranik 99262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 993491d8ee7SSantosh Puranik 9941e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 995491d8ee7SSantosh Puranik if (!rfSource.empty()) 996491d8ee7SSantosh Puranik { 997ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 998ac106bf6SEd Tanous rfSource; 999491d8ee7SSantosh Puranik } 1000cd9a4666SKonstantin Aladyshev 1001cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1002cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1003ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10041e1e598dSJonathan Doman }); 1005491d8ee7SSantosh Puranik } 1006491d8ee7SSantosh Puranik 1007491d8ee7SSantosh Puranik /** 1008c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1009c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1010c21865c4SKonstantin Aladyshev * state 1011491d8ee7SSantosh Puranik * 1012ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1013491d8ee7SSantosh Puranik * 1014491d8ee7SSantosh Puranik * @return None. 1015491d8ee7SSantosh Puranik */ 1016491d8ee7SSantosh Puranik 1017ac106bf6SEd Tanous inline void processBootOverrideEnable( 1018ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1019c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1020c21865c4SKonstantin Aladyshev { 1021c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1022c21865c4SKonstantin Aladyshev { 1023ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1024ac106bf6SEd Tanous "Disabled"; 1025c21865c4SKonstantin Aladyshev return; 1026c21865c4SKonstantin Aladyshev } 1027c21865c4SKonstantin Aladyshev 1028c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1029c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10301e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10311e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10321e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10331e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1034ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1035491d8ee7SSantosh Puranik if (ec) 1036491d8ee7SSantosh Puranik { 1037b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1038ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1039491d8ee7SSantosh Puranik return; 1040491d8ee7SSantosh Puranik } 1041491d8ee7SSantosh Puranik 1042c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1043c21865c4SKonstantin Aladyshev { 1044ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1045ac106bf6SEd Tanous "Once"; 1046c21865c4SKonstantin Aladyshev } 1047c21865c4SKonstantin Aladyshev else 1048c21865c4SKonstantin Aladyshev { 1049ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1050c21865c4SKonstantin Aladyshev "Continuous"; 1051c21865c4SKonstantin Aladyshev } 10521e1e598dSJonathan Doman }); 1053491d8ee7SSantosh Puranik } 1054491d8ee7SSantosh Puranik 1055491d8ee7SSantosh Puranik /** 1056c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1057c21865c4SKonstantin Aladyshev * 1058ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1059c21865c4SKonstantin Aladyshev * 1060c21865c4SKonstantin Aladyshev * @return None. 1061c21865c4SKonstantin Aladyshev */ 1062c21865c4SKonstantin Aladyshev 1063c21865c4SKonstantin Aladyshev inline void 1064ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1065c21865c4SKonstantin Aladyshev { 10661e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10671e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10681e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10691e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1070ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10711e1e598dSJonathan Doman const bool bootOverrideEnable) { 1072c21865c4SKonstantin Aladyshev if (ec) 1073c21865c4SKonstantin Aladyshev { 10745ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10755ef735c8SNan Zhou { 10765ef735c8SNan Zhou return; 10775ef735c8SNan Zhou } 1078b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1079ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1080c21865c4SKonstantin Aladyshev return; 1081c21865c4SKonstantin Aladyshev } 1082c21865c4SKonstantin Aladyshev 1083ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 10841e1e598dSJonathan Doman }); 1085c21865c4SKonstantin Aladyshev } 1086c21865c4SKonstantin Aladyshev 1087c21865c4SKonstantin Aladyshev /** 1088c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1089c21865c4SKonstantin Aladyshev * 1090ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1091c21865c4SKonstantin Aladyshev * 1092c21865c4SKonstantin Aladyshev * @return None. 1093c21865c4SKonstantin Aladyshev */ 1094ac106bf6SEd Tanous inline void 1095ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1096c21865c4SKonstantin Aladyshev { 109762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1098c21865c4SKonstantin Aladyshev 1099ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1100ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1101ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1102c21865c4SKonstantin Aladyshev } 1103c21865c4SKonstantin Aladyshev 1104c21865c4SKonstantin Aladyshev /** 1105c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1106c0557e1aSGunnar Mills * 1107c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1108c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1109c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1110c0557e1aSGunnar Mills * last power operation time. 1111c0557e1aSGunnar Mills * 1112ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1113c0557e1aSGunnar Mills * 1114c0557e1aSGunnar Mills * @return None. 1115c0557e1aSGunnar Mills */ 1116ac106bf6SEd Tanous inline void 1117ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1118c0557e1aSGunnar Mills { 111962598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1120c0557e1aSGunnar Mills 11211e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11221e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11231e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11241e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1125ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1126ac106bf6SEd Tanous uint64_t lastResetTime) { 1127c0557e1aSGunnar Mills if (ec) 1128c0557e1aSGunnar Mills { 112962598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1130c0557e1aSGunnar Mills return; 1131c0557e1aSGunnar Mills } 1132c0557e1aSGunnar Mills 1133c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1134c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11351e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1136c0557e1aSGunnar Mills 1137c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1138ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 11392b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11401e1e598dSJonathan Doman }); 1141c0557e1aSGunnar Mills } 1142c0557e1aSGunnar Mills 1143c0557e1aSGunnar Mills /** 1144797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1145797d5daeSCorey Hardesty * 1146797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1147797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1148797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1149797d5daeSCorey Hardesty * dbus. 1150797d5daeSCorey Hardesty * 1151ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1152797d5daeSCorey Hardesty * 1153797d5daeSCorey Hardesty * @return None. 1154797d5daeSCorey Hardesty */ 1155ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1156ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1157797d5daeSCorey Hardesty { 115862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1159797d5daeSCorey Hardesty 1160797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1161797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1162797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1163797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1164ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1165ac106bf6SEd Tanous const boost::system::error_code& ec, 1166797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1167797d5daeSCorey Hardesty if (ec) 1168797d5daeSCorey Hardesty { 1169797d5daeSCorey Hardesty if (ec.value() != EBADR) 1170797d5daeSCorey Hardesty { 117162598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1172ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1173797d5daeSCorey Hardesty } 1174797d5daeSCorey Hardesty return; 1175797d5daeSCorey Hardesty } 1176797d5daeSCorey Hardesty 1177797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1178797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1179797d5daeSCorey Hardesty 1180797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1181797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1182797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1183797d5daeSCorey Hardesty 1184797d5daeSCorey Hardesty if (!success) 1185797d5daeSCorey Hardesty { 1186ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1187797d5daeSCorey Hardesty return; 1188797d5daeSCorey Hardesty } 1189797d5daeSCorey Hardesty 1190797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1191797d5daeSCorey Hardesty { 1192ac106bf6SEd Tanous asyncResp->res 1193ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1194797d5daeSCorey Hardesty *attemptsLeft; 1195797d5daeSCorey Hardesty } 1196797d5daeSCorey Hardesty 1197797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1198797d5daeSCorey Hardesty { 1199ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1200797d5daeSCorey Hardesty *retryAttempts; 1201797d5daeSCorey Hardesty } 1202797d5daeSCorey Hardesty }); 1203797d5daeSCorey Hardesty } 1204797d5daeSCorey Hardesty 1205797d5daeSCorey Hardesty /** 12066bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12076bd5a8d2SGunnar Mills * 1208ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12096bd5a8d2SGunnar Mills * 12106bd5a8d2SGunnar Mills * @return None. 12116bd5a8d2SGunnar Mills */ 1212797d5daeSCorey Hardesty inline void 1213ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12146bd5a8d2SGunnar Mills { 121562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12166bd5a8d2SGunnar Mills 12171e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12181e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12191e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12201e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1221ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1222ac106bf6SEd Tanous bool autoRebootEnabled) { 12236bd5a8d2SGunnar Mills if (ec) 12246bd5a8d2SGunnar Mills { 1225797d5daeSCorey Hardesty if (ec.value() != EBADR) 1226797d5daeSCorey Hardesty { 122762598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1228ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1229797d5daeSCorey Hardesty } 12306bd5a8d2SGunnar Mills return; 12316bd5a8d2SGunnar Mills } 12326bd5a8d2SGunnar Mills 123362598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1234e05aec50SEd Tanous if (autoRebootEnabled) 12356bd5a8d2SGunnar Mills { 1236ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12376bd5a8d2SGunnar Mills "RetryAttempts"; 12386bd5a8d2SGunnar Mills } 12396bd5a8d2SGunnar Mills else 12406bd5a8d2SGunnar Mills { 1241ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1242ac106bf6SEd Tanous "Disabled"; 12436bd5a8d2SGunnar Mills } 1244ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 124569f35306SGunnar Mills 124669f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 124769f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 124869f35306SGunnar Mills // RetryAttempts. 1249ac106bf6SEd Tanous asyncResp->res 1250ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1251ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 12521e1e598dSJonathan Doman }); 12536bd5a8d2SGunnar Mills } 12546bd5a8d2SGunnar Mills 12556bd5a8d2SGunnar Mills /** 1256797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1257797d5daeSCorey Hardesty * 1258ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1259797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1260797d5daeSCorey Hardesty * 1261797d5daeSCorey Hardesty *@return None. 1262797d5daeSCorey Hardesty */ 1263797d5daeSCorey Hardesty 1264ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1265ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1266797d5daeSCorey Hardesty const uint32_t retryAttempts) 1267797d5daeSCorey Hardesty { 126862598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 12699ae226faSGeorge Liu sdbusplus::asio::setProperty( 12709ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 12719ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 12729ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 12739ae226faSGeorge Liu retryAttempts, [asyncResp](const boost::system::error_code& ec) { 1274797d5daeSCorey Hardesty if (ec) 1275797d5daeSCorey Hardesty { 127662598e31SEd Tanous BMCWEB_LOG_ERROR( 127762598e31SEd Tanous "DBUS response error: Set setAutomaticRetryAttempts{}", ec); 1278ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1279797d5daeSCorey Hardesty return; 1280797d5daeSCorey Hardesty } 12819ae226faSGeorge Liu }); 1282797d5daeSCorey Hardesty } 1283797d5daeSCorey Hardesty 12848d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 12858d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 12868d69c668SEd Tanous { 12878d69c668SEd Tanous if (value == 12888d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 12898d69c668SEd Tanous { 12908d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 12918d69c668SEd Tanous } 12928d69c668SEd Tanous if (value == 12938d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 12948d69c668SEd Tanous { 12958d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 12968d69c668SEd Tanous } 12978d69c668SEd Tanous if (value == 12983a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 12998d69c668SEd Tanous { 13008d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13018d69c668SEd Tanous } 13028d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13038d69c668SEd Tanous { 13048d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13058d69c668SEd Tanous } 13068d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13078d69c668SEd Tanous } 1308797d5daeSCorey Hardesty /** 1309c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1310c6a620f2SGeorge Liu * 1311ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1312c6a620f2SGeorge Liu * 1313c6a620f2SGeorge Liu * @return None. 1314c6a620f2SGeorge Liu */ 13158d1b46d7Szhanghch05 inline void 1316ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1317c6a620f2SGeorge Liu { 131862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1319c6a620f2SGeorge Liu 13201e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13211e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13221e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13231e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1324ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13255e7e2dc5SEd Tanous const std::string& policy) { 1326c6a620f2SGeorge Liu if (ec) 1327c6a620f2SGeorge Liu { 132862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1329c6a620f2SGeorge Liu return; 1330c6a620f2SGeorge Liu } 13318d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 13328d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 13338d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1334c6a620f2SGeorge Liu { 1335ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1336c6a620f2SGeorge Liu return; 1337c6a620f2SGeorge Liu } 1338c6a620f2SGeorge Liu 13398d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 13401e1e598dSJonathan Doman }); 1341c6a620f2SGeorge Liu } 1342c6a620f2SGeorge Liu 1343c6a620f2SGeorge Liu /** 13449dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 13459dcfe8c1SAlbert Zhang * 13469dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 13479dcfe8c1SAlbert Zhang * 13489dcfe8c1SAlbert Zhang * @return None. 13499dcfe8c1SAlbert Zhang */ 13509dcfe8c1SAlbert Zhang inline void 13519dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13529dcfe8c1SAlbert Zhang { 135362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 13549dcfe8c1SAlbert Zhang 13559dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 13569dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13579dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 13589dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 13599dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 13609dcfe8c1SAlbert Zhang if (ec) 13619dcfe8c1SAlbert Zhang { 13629dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 13639dcfe8c1SAlbert Zhang { 1364b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 13659dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 13669dcfe8c1SAlbert Zhang } 13679dcfe8c1SAlbert Zhang return; 13689dcfe8c1SAlbert Zhang } 13699dcfe8c1SAlbert Zhang 13709dcfe8c1SAlbert Zhang if (value) 13719dcfe8c1SAlbert Zhang { 13729dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault"; 13739dcfe8c1SAlbert Zhang } 13749dcfe8c1SAlbert Zhang else 13759dcfe8c1SAlbert Zhang { 13769dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never"; 13779dcfe8c1SAlbert Zhang } 13789dcfe8c1SAlbert Zhang }); 13799dcfe8c1SAlbert Zhang } 13809dcfe8c1SAlbert Zhang 13819dcfe8c1SAlbert Zhang /** 13821981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13831981771bSAli Ahmed * TPM is required for booting the host. 13841981771bSAli Ahmed * 1385ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 13861981771bSAli Ahmed * 13871981771bSAli Ahmed * @return None. 13881981771bSAli Ahmed */ 13891981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1390ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13911981771bSAli Ahmed { 139262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1393e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1394e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1395e99073f5SGeorge Liu dbus::utility::getSubTree( 1396e99073f5SGeorge Liu "/", 0, interfaces, 1397ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1398b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 13991981771bSAli Ahmed if (ec) 14001981771bSAli Ahmed { 140162598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", 140262598e31SEd Tanous ec); 14031981771bSAli Ahmed // This is an optional D-Bus object so just return if 14041981771bSAli Ahmed // error occurs 14051981771bSAli Ahmed return; 14061981771bSAli Ahmed } 140726f6976fSEd Tanous if (subtree.empty()) 14081981771bSAli Ahmed { 14091981771bSAli Ahmed // As noted above, this is an optional interface so just return 14101981771bSAli Ahmed // if there is no instance found 14111981771bSAli Ahmed return; 14121981771bSAli Ahmed } 14131981771bSAli Ahmed 14141981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14151981771bSAli Ahmed if (subtree.size() > 1) 14161981771bSAli Ahmed { 141762598e31SEd Tanous BMCWEB_LOG_DEBUG( 141862598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 141962598e31SEd Tanous subtree.size()); 14201981771bSAli Ahmed // Throw an internal Error and return 1421ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14221981771bSAli Ahmed return; 14231981771bSAli Ahmed } 14241981771bSAli Ahmed 14251981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14261981771bSAli Ahmed // field 14271981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14281981771bSAli Ahmed { 142962598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1430ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14311981771bSAli Ahmed return; 14321981771bSAli Ahmed } 14331981771bSAli Ahmed 14341981771bSAli Ahmed const std::string& path = subtree[0].first; 14351981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14361981771bSAli Ahmed 14371981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14381e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14391e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14401e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1441ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1442ac106bf6SEd Tanous bool tpmRequired) { 14438a592810SEd Tanous if (ec2) 14441981771bSAli Ahmed { 1445b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}", 144662598e31SEd Tanous ec2); 1447ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14481981771bSAli Ahmed return; 14491981771bSAli Ahmed } 14501981771bSAli Ahmed 14511e1e598dSJonathan Doman if (tpmRequired) 14521981771bSAli Ahmed { 1453ac106bf6SEd Tanous asyncResp->res 1454ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14551981771bSAli Ahmed "Required"; 14561981771bSAli Ahmed } 14571981771bSAli Ahmed else 14581981771bSAli Ahmed { 1459ac106bf6SEd Tanous asyncResp->res 1460ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14611981771bSAli Ahmed "Disabled"; 14621981771bSAli Ahmed } 14631e1e598dSJonathan Doman }); 1464e99073f5SGeorge Liu }); 14651981771bSAli Ahmed } 14661981771bSAli Ahmed 14671981771bSAli Ahmed /** 14681c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14691c05dae3SAli Ahmed * TPM is required for booting the host. 14701c05dae3SAli Ahmed * 1471ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14721c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14731c05dae3SAli Ahmed * 14741c05dae3SAli Ahmed * @return None. 14751c05dae3SAli Ahmed */ 14761c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1477ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 14781c05dae3SAli Ahmed { 147962598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1480e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1481e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1482e99073f5SGeorge Liu dbus::utility::getSubTree( 1483e99073f5SGeorge Liu "/", 0, interfaces, 1484ac106bf6SEd Tanous [asyncResp, 1485e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1486e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 14871c05dae3SAli Ahmed if (ec) 14881c05dae3SAli Ahmed { 1489b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", 149062598e31SEd Tanous ec); 1491ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14921c05dae3SAli Ahmed return; 14931c05dae3SAli Ahmed } 149426f6976fSEd Tanous if (subtree.empty()) 14951c05dae3SAli Ahmed { 1496ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 14971c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 14981c05dae3SAli Ahmed return; 14991c05dae3SAli Ahmed } 15001c05dae3SAli Ahmed 15011c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15021c05dae3SAli Ahmed if (subtree.size() > 1) 15031c05dae3SAli Ahmed { 150462598e31SEd Tanous BMCWEB_LOG_DEBUG( 150562598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 150662598e31SEd Tanous subtree.size()); 15071c05dae3SAli Ahmed // Throw an internal Error and return 1508ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15091c05dae3SAli Ahmed return; 15101c05dae3SAli Ahmed } 15111c05dae3SAli Ahmed 15121c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15131c05dae3SAli Ahmed // field 15141c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15151c05dae3SAli Ahmed { 151662598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1517ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15181c05dae3SAli Ahmed return; 15191c05dae3SAli Ahmed } 15201c05dae3SAli Ahmed 15211c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15221c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15231c05dae3SAli Ahmed 15241c05dae3SAli Ahmed if (serv.empty()) 15251c05dae3SAli Ahmed { 152662598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1527ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15281c05dae3SAli Ahmed return; 15291c05dae3SAli Ahmed } 15301c05dae3SAli Ahmed 15311c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 15329ae226faSGeorge Liu sdbusplus::asio::setProperty( 15339ae226faSGeorge Liu *crow::connections::systemBus, serv, path, 15349ae226faSGeorge Liu "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired, 1535ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 15368a592810SEd Tanous if (ec2) 15371c05dae3SAli Ahmed { 1538b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 153962598e31SEd Tanous "DBUS response error: Set TrustedModuleRequiredToBoot{}", 154062598e31SEd Tanous ec2); 1541ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15421c05dae3SAli Ahmed return; 15431c05dae3SAli Ahmed } 154462598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done."); 15459ae226faSGeorge Liu }); 1546e99073f5SGeorge Liu }); 15471c05dae3SAli Ahmed } 15481c05dae3SAli Ahmed 15491c05dae3SAli Ahmed /** 1550491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1551491d8ee7SSantosh Puranik * 1552ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1553cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1554cd9a4666SKonstantin Aladyshev * @return Integer error code. 1555cd9a4666SKonstantin Aladyshev */ 1556ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1557cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1558cd9a4666SKonstantin Aladyshev { 1559c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1560cd9a4666SKonstantin Aladyshev 1561c21865c4SKonstantin Aladyshev if (!bootType) 1562cd9a4666SKonstantin Aladyshev { 1563c21865c4SKonstantin Aladyshev return; 1564c21865c4SKonstantin Aladyshev } 1565c21865c4SKonstantin Aladyshev 1566cd9a4666SKonstantin Aladyshev // Source target specified 156762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1568cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1569cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1570cd9a4666SKonstantin Aladyshev { 1571cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1572cd9a4666SKonstantin Aladyshev } 1573cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1574cd9a4666SKonstantin Aladyshev { 1575cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1576cd9a4666SKonstantin Aladyshev } 1577cd9a4666SKonstantin Aladyshev else 1578cd9a4666SKonstantin Aladyshev { 157962598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 158062598e31SEd Tanous "BootSourceOverrideMode: {}", 158162598e31SEd Tanous *bootType); 1582ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1583cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1584cd9a4666SKonstantin Aladyshev return; 1585cd9a4666SKonstantin Aladyshev } 1586cd9a4666SKonstantin Aladyshev 1587cd9a4666SKonstantin Aladyshev // Act on validated parameters 158862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1589cd9a4666SKonstantin Aladyshev 15909ae226faSGeorge Liu sdbusplus::asio::setProperty( 15919ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 15929ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 15939ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr, 1594ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1595cd9a4666SKonstantin Aladyshev if (ec) 1596cd9a4666SKonstantin Aladyshev { 1597cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1598cd9a4666SKonstantin Aladyshev { 1599ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1600cd9a4666SKonstantin Aladyshev return; 1601cd9a4666SKonstantin Aladyshev } 1602b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1603ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1604cd9a4666SKonstantin Aladyshev return; 1605cd9a4666SKonstantin Aladyshev } 160662598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type update done."); 16079ae226faSGeorge Liu }); 1608cd9a4666SKonstantin Aladyshev } 1609cd9a4666SKonstantin Aladyshev 1610cd9a4666SKonstantin Aladyshev /** 1611cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1612cd9a4666SKonstantin Aladyshev * 1613ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1614ac106bf6SEd Tanous * message. 1615c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1616c21865c4SKonstantin Aladyshev * @return Integer error code. 1617c21865c4SKonstantin Aladyshev */ 1618ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1619c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1620c21865c4SKonstantin Aladyshev { 1621c21865c4SKonstantin Aladyshev if (!bootEnable) 1622c21865c4SKonstantin Aladyshev { 1623c21865c4SKonstantin Aladyshev return; 1624c21865c4SKonstantin Aladyshev } 1625c21865c4SKonstantin Aladyshev // Source target specified 162662598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1627c21865c4SKonstantin Aladyshev 1628c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1629c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1630c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1631c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1632c21865c4SKonstantin Aladyshev { 1633c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1634c21865c4SKonstantin Aladyshev } 1635c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1636c21865c4SKonstantin Aladyshev { 1637c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1638c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1639c21865c4SKonstantin Aladyshev } 1640c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1641c21865c4SKonstantin Aladyshev { 1642c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1643c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1644c21865c4SKonstantin Aladyshev } 1645c21865c4SKonstantin Aladyshev else 1646c21865c4SKonstantin Aladyshev { 164762598e31SEd Tanous BMCWEB_LOG_DEBUG( 164862598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 164962598e31SEd Tanous *bootEnable); 1650ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1651c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1652c21865c4SKonstantin Aladyshev return; 1653c21865c4SKonstantin Aladyshev } 1654c21865c4SKonstantin Aladyshev 1655c21865c4SKonstantin Aladyshev // Act on validated parameters 165662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1657c21865c4SKonstantin Aladyshev 16589ae226faSGeorge Liu sdbusplus::asio::setProperty( 16599ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 16609ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 16619ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable, 1662ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 16638a592810SEd Tanous if (ec2) 1664c21865c4SKonstantin Aladyshev { 1665b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 1666ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1667c21865c4SKonstantin Aladyshev return; 1668c21865c4SKonstantin Aladyshev } 166962598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot override enable update done."); 16709ae226faSGeorge Liu }); 1671c21865c4SKonstantin Aladyshev 1672c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1673c21865c4SKonstantin Aladyshev { 1674c21865c4SKonstantin Aladyshev return; 1675c21865c4SKonstantin Aladyshev } 1676c21865c4SKonstantin Aladyshev 1677c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1678c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 167962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 168062598e31SEd Tanous bootOverridePersistent); 1681c21865c4SKonstantin Aladyshev 16829ae226faSGeorge Liu sdbusplus::asio::setProperty( 16839ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 16849ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot/one_time", 16859ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent, 1686ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1687c21865c4SKonstantin Aladyshev if (ec) 1688c21865c4SKonstantin Aladyshev { 1689b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1690ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1691c21865c4SKonstantin Aladyshev return; 1692c21865c4SKonstantin Aladyshev } 169362598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot one_time update done."); 16949ae226faSGeorge Liu }); 1695c21865c4SKonstantin Aladyshev } 1696c21865c4SKonstantin Aladyshev 1697c21865c4SKonstantin Aladyshev /** 1698c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1699c21865c4SKonstantin Aladyshev * 1700ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1701491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1702491d8ee7SSantosh Puranik * 1703265c1602SJohnathan Mantey * @return Integer error code. 1704491d8ee7SSantosh Puranik */ 1705ac106bf6SEd Tanous inline void 1706ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1707cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1708491d8ee7SSantosh Puranik { 1709c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1710c21865c4SKonstantin Aladyshev std::string bootModeStr; 1711944ffaf9SJohnathan Mantey 1712c21865c4SKonstantin Aladyshev if (!bootSource) 1713491d8ee7SSantosh Puranik { 1714c21865c4SKonstantin Aladyshev return; 1715c21865c4SKonstantin Aladyshev } 1716c21865c4SKonstantin Aladyshev 1717491d8ee7SSantosh Puranik // Source target specified 171862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1719491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1720ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1721ac106bf6SEd Tanous bootModeStr) != 0) 1722491d8ee7SSantosh Puranik { 172362598e31SEd Tanous BMCWEB_LOG_DEBUG( 172462598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 172562598e31SEd Tanous *bootSource); 1726ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1727491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1728491d8ee7SSantosh Puranik return; 1729491d8ee7SSantosh Puranik } 1730491d8ee7SSantosh Puranik 1731944ffaf9SJohnathan Mantey // Act on validated parameters 173262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 173362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1734944ffaf9SJohnathan Mantey 17359ae226faSGeorge Liu sdbusplus::asio::setProperty( 17369ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17379ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 17389ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr, 1739ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1740491d8ee7SSantosh Puranik if (ec) 1741491d8ee7SSantosh Puranik { 1742b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1743ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1744491d8ee7SSantosh Puranik return; 1745491d8ee7SSantosh Puranik } 174662598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source update done."); 17479ae226faSGeorge Liu }); 1748944ffaf9SJohnathan Mantey 17499ae226faSGeorge Liu sdbusplus::asio::setProperty( 17509ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17519ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 17529ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr, 1753ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1754491d8ee7SSantosh Puranik if (ec) 1755491d8ee7SSantosh Puranik { 1756b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1757ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1758491d8ee7SSantosh Puranik return; 1759491d8ee7SSantosh Puranik } 176062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode update done."); 17619ae226faSGeorge Liu }); 1762cd9a4666SKonstantin Aladyshev } 1763944ffaf9SJohnathan Mantey 1764cd9a4666SKonstantin Aladyshev /** 1765c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1766491d8ee7SSantosh Puranik * 1767ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1768491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1769cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1770491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1771491d8ee7SSantosh Puranik * 1772265c1602SJohnathan Mantey * @return Integer error code. 1773491d8ee7SSantosh Puranik */ 1774c21865c4SKonstantin Aladyshev 1775ac106bf6SEd Tanous inline void 1776ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1777c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1778c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1779c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1780491d8ee7SSantosh Puranik { 178162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1782491d8ee7SSantosh Puranik 1783ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1784ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1785ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1786491d8ee7SSantosh Puranik } 1787491d8ee7SSantosh Puranik 1788c6a620f2SGeorge Liu /** 178998e386ecSGunnar Mills * @brief Sets AssetTag 179098e386ecSGunnar Mills * 1791ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 179298e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 179398e386ecSGunnar Mills * 179498e386ecSGunnar Mills * @return None. 179598e386ecSGunnar Mills */ 1796ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 179798e386ecSGunnar Mills const std::string& assetTag) 179898e386ecSGunnar Mills { 1799e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1800e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1801e99073f5SGeorge Liu dbus::utility::getSubTree( 1802e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1803ac106bf6SEd Tanous [asyncResp, 1804e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1805b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 180698e386ecSGunnar Mills if (ec) 180798e386ecSGunnar Mills { 180862598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1809ac106bf6SEd Tanous messages::internalError(asyncResp->res); 181098e386ecSGunnar Mills return; 181198e386ecSGunnar Mills } 181226f6976fSEd Tanous if (subtree.empty()) 181398e386ecSGunnar Mills { 181462598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1815ac106bf6SEd Tanous messages::internalError(asyncResp->res); 181698e386ecSGunnar Mills return; 181798e386ecSGunnar Mills } 181898e386ecSGunnar Mills // Assume only 1 system D-Bus object 181998e386ecSGunnar Mills // Throw an error if there is more than 1 182098e386ecSGunnar Mills if (subtree.size() > 1) 182198e386ecSGunnar Mills { 182262598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1823ac106bf6SEd Tanous messages::internalError(asyncResp->res); 182498e386ecSGunnar Mills return; 182598e386ecSGunnar Mills } 182698e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 182798e386ecSGunnar Mills { 182862598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1829ac106bf6SEd Tanous messages::internalError(asyncResp->res); 183098e386ecSGunnar Mills return; 183198e386ecSGunnar Mills } 183298e386ecSGunnar Mills 183398e386ecSGunnar Mills const std::string& path = subtree[0].first; 183498e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 183598e386ecSGunnar Mills 183698e386ecSGunnar Mills if (service.empty()) 183798e386ecSGunnar Mills { 183862598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1839ac106bf6SEd Tanous messages::internalError(asyncResp->res); 184098e386ecSGunnar Mills return; 184198e386ecSGunnar Mills } 184298e386ecSGunnar Mills 18439ae226faSGeorge Liu sdbusplus::asio::setProperty( 18449ae226faSGeorge Liu *crow::connections::systemBus, service, path, 18459ae226faSGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 18469ae226faSGeorge Liu assetTag, [asyncResp](const boost::system::error_code& ec2) { 184798e386ecSGunnar Mills if (ec2) 184898e386ecSGunnar Mills { 1849b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}", 185062598e31SEd Tanous ec2); 1851ac106bf6SEd Tanous messages::internalError(asyncResp->res); 185298e386ecSGunnar Mills return; 185398e386ecSGunnar Mills } 18549ae226faSGeorge Liu }); 1855e99073f5SGeorge Liu }); 185698e386ecSGunnar Mills } 185798e386ecSGunnar Mills 185898e386ecSGunnar Mills /** 18599dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 18609dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 18619dcfe8c1SAlbert Zhang * 18629dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 18639dcfe8c1SAlbert Zhang * stopBootOnFault 18649dcfe8c1SAlbert Zhang * 18659dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 18669dcfe8c1SAlbert Zhang */ 18679dcfe8c1SAlbert Zhang inline std::optional<bool> 18689dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 18699dcfe8c1SAlbert Zhang { 18709dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 18719dcfe8c1SAlbert Zhang { 18729dcfe8c1SAlbert Zhang return true; 18739dcfe8c1SAlbert Zhang } 18749dcfe8c1SAlbert Zhang 18759dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 18769dcfe8c1SAlbert Zhang { 18779dcfe8c1SAlbert Zhang return false; 18789dcfe8c1SAlbert Zhang } 18799dcfe8c1SAlbert Zhang 18809dcfe8c1SAlbert Zhang return std::nullopt; 18819dcfe8c1SAlbert Zhang } 18829dcfe8c1SAlbert Zhang 18839dcfe8c1SAlbert Zhang /** 18849dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 18859dcfe8c1SAlbert Zhang * 1886fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 18879dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 18889dcfe8c1SAlbert Zhang * 18899dcfe8c1SAlbert Zhang * @return None. 18909dcfe8c1SAlbert Zhang */ 1891fc3edfddSEd Tanous inline void 1892fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 18939dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 18949dcfe8c1SAlbert Zhang { 189562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 18969dcfe8c1SAlbert Zhang 18979dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 18989dcfe8c1SAlbert Zhang if (!stopBootEnabled) 18999dcfe8c1SAlbert Zhang { 190062598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 190162598e31SEd Tanous stopBootOnFault); 1902fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 19039dcfe8c1SAlbert Zhang "StopBootOnFault"); 19049dcfe8c1SAlbert Zhang return; 19059dcfe8c1SAlbert Zhang } 19069dcfe8c1SAlbert Zhang 1907fc3edfddSEd Tanous sdbusplus::asio::setProperty( 1908fc3edfddSEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 19099dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 1910fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1911fc3edfddSEd Tanous *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) { 19129dcfe8c1SAlbert Zhang if (ec) 19139dcfe8c1SAlbert Zhang { 19149dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 19159dcfe8c1SAlbert Zhang { 1916b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1917fc3edfddSEd Tanous messages::internalError(asyncResp->res); 19189dcfe8c1SAlbert Zhang } 19199dcfe8c1SAlbert Zhang return; 19209dcfe8c1SAlbert Zhang } 19219dcfe8c1SAlbert Zhang }); 19229dcfe8c1SAlbert Zhang } 19239dcfe8c1SAlbert Zhang 19249dcfe8c1SAlbert Zhang /** 192569f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 192669f35306SGunnar Mills * 1927ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 192869f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 192969f35306SGunnar Mills * 193069f35306SGunnar Mills * @return None. 193169f35306SGunnar Mills */ 1932ac106bf6SEd Tanous inline void 1933ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1934f23b7296SEd Tanous const std::string& automaticRetryConfig) 193569f35306SGunnar Mills { 193662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 193769f35306SGunnar Mills 193869f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1939543f4400SEd Tanous bool autoRebootEnabled = false; 194069f35306SGunnar Mills 194169f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 194269f35306SGunnar Mills { 194369f35306SGunnar Mills autoRebootEnabled = false; 194469f35306SGunnar Mills } 194569f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 194669f35306SGunnar Mills { 194769f35306SGunnar Mills autoRebootEnabled = true; 194869f35306SGunnar Mills } 194969f35306SGunnar Mills else 195069f35306SGunnar Mills { 195162598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 195262598e31SEd Tanous automaticRetryConfig); 1953ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 195469f35306SGunnar Mills "AutomaticRetryConfig"); 195569f35306SGunnar Mills return; 195669f35306SGunnar Mills } 195769f35306SGunnar Mills 19589ae226faSGeorge Liu sdbusplus::asio::setProperty( 19599ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 19609ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/auto_reboot", 19619ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 19629ae226faSGeorge Liu autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) { 196369f35306SGunnar Mills if (ec) 196469f35306SGunnar Mills { 1965b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1966ac106bf6SEd Tanous messages::internalError(asyncResp->res); 196769f35306SGunnar Mills return; 196869f35306SGunnar Mills } 19699ae226faSGeorge Liu }); 197069f35306SGunnar Mills } 197169f35306SGunnar Mills 19728d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 19738d69c668SEd Tanous { 19748d69c668SEd Tanous if (policy == "AlwaysOn") 19758d69c668SEd Tanous { 19768d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 19778d69c668SEd Tanous } 19788d69c668SEd Tanous if (policy == "AlwaysOff") 19798d69c668SEd Tanous { 19808d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 19818d69c668SEd Tanous } 19828d69c668SEd Tanous if (policy == "LastState") 19838d69c668SEd Tanous { 19848d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 19858d69c668SEd Tanous } 19868d69c668SEd Tanous return ""; 19878d69c668SEd Tanous } 19888d69c668SEd Tanous 198969f35306SGunnar Mills /** 1990c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1991c6a620f2SGeorge Liu * 1992ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1993c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1994c6a620f2SGeorge Liu * 1995c6a620f2SGeorge Liu * @return None. 1996c6a620f2SGeorge Liu */ 19978d1b46d7Szhanghch05 inline void 1998ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19998d69c668SEd Tanous std::string_view policy) 2000c6a620f2SGeorge Liu { 200162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 2002c6a620f2SGeorge Liu 20038d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 2004c6a620f2SGeorge Liu 20058d69c668SEd Tanous if (powerRestorePolicy.empty()) 2006c6a620f2SGeorge Liu { 2007ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 20084e69c904SGunnar Mills "PowerRestorePolicy"); 2009c6a620f2SGeorge Liu return; 2010c6a620f2SGeorge Liu } 2011c6a620f2SGeorge Liu 20129ae226faSGeorge Liu sdbusplus::asio::setProperty( 20139ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20149ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 20159ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 20169ae226faSGeorge Liu powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) { 2017c6a620f2SGeorge Liu if (ec) 2018c6a620f2SGeorge Liu { 2019b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2020ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2021c6a620f2SGeorge Liu return; 2022c6a620f2SGeorge Liu } 20239ae226faSGeorge Liu }); 2024c6a620f2SGeorge Liu } 2025c6a620f2SGeorge Liu 2026a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 2027a6349918SAppaRao Puli /** 2028a6349918SAppaRao Puli * @brief Retrieves provisioning status 2029a6349918SAppaRao Puli * 2030ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 2031a6349918SAppaRao Puli * 2032a6349918SAppaRao Puli * @return None. 2033a6349918SAppaRao Puli */ 2034ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 2035a6349918SAppaRao Puli { 203662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 2037bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2038bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 2039bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 2040ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2041b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 2042b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2043ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2044ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 204550626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 204650626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 204750626f4fSJames Feist 2048a6349918SAppaRao Puli if (ec) 2049a6349918SAppaRao Puli { 205062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 2051b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2052b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2053a6349918SAppaRao Puli return; 2054a6349918SAppaRao Puli } 2055a6349918SAppaRao Puli 2056a6349918SAppaRao Puli const bool* provState = nullptr; 2057a6349918SAppaRao Puli const bool* lockState = nullptr; 2058bc1d29deSKrzysztof Grobelny 2059bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 20600d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 20610d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 2062bc1d29deSKrzysztof Grobelny 2063bc1d29deSKrzysztof Grobelny if (!success) 2064a6349918SAppaRao Puli { 2065ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2066bc1d29deSKrzysztof Grobelny return; 2067a6349918SAppaRao Puli } 2068a6349918SAppaRao Puli 2069a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2070a6349918SAppaRao Puli { 207162598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 2072ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2073a6349918SAppaRao Puli return; 2074a6349918SAppaRao Puli } 2075a6349918SAppaRao Puli 2076a6349918SAppaRao Puli if (*provState == true) 2077a6349918SAppaRao Puli { 2078a6349918SAppaRao Puli if (*lockState == true) 2079a6349918SAppaRao Puli { 2080a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2081a6349918SAppaRao Puli } 2082a6349918SAppaRao Puli else 2083a6349918SAppaRao Puli { 2084a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2085a6349918SAppaRao Puli } 2086a6349918SAppaRao Puli } 2087a6349918SAppaRao Puli else 2088a6349918SAppaRao Puli { 2089a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2090a6349918SAppaRao Puli } 2091bc1d29deSKrzysztof Grobelny }); 2092a6349918SAppaRao Puli } 2093a6349918SAppaRao Puli #endif 2094a6349918SAppaRao Puli 2095491d8ee7SSantosh Puranik /** 20966b9ac4f2SChris Cain * @brief Translate the PowerMode string to enum value 20973a2d0424SChris Cain * 20986b9ac4f2SChris Cain * @param[in] modeString PowerMode string to be translated 20993a2d0424SChris Cain * 21006b9ac4f2SChris Cain * @return PowerMode enum 21013a2d0424SChris Cain */ 21026b9ac4f2SChris Cain inline computer_system::PowerMode 21036b9ac4f2SChris Cain translatePowerModeString(const std::string& modeString) 21043a2d0424SChris Cain { 2105b6655101SChris Cain using PowerMode = computer_system::PowerMode; 2106b6655101SChris Cain 21076b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 21083a2d0424SChris Cain { 21096b9ac4f2SChris Cain return PowerMode::Static; 21103a2d0424SChris Cain } 21116b9ac4f2SChris Cain if (modeString == 21120fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 21133a2d0424SChris Cain { 21146b9ac4f2SChris Cain return PowerMode::MaximumPerformance; 21153a2d0424SChris Cain } 21166b9ac4f2SChris Cain if (modeString == 21170fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 21183a2d0424SChris Cain { 21196b9ac4f2SChris Cain return PowerMode::PowerSaving; 2120b6655101SChris Cain } 21216b9ac4f2SChris Cain if (modeString == 2122b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance") 2123b6655101SChris Cain { 21246b9ac4f2SChris Cain return PowerMode::BalancedPerformance; 2125b6655101SChris Cain } 21266b9ac4f2SChris Cain if (modeString == 2127b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance") 2128b6655101SChris Cain { 21296b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPerformance; 2130b6655101SChris Cain } 21316b9ac4f2SChris Cain if (modeString == 2132b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower") 2133b6655101SChris Cain { 21346b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPower; 21353a2d0424SChris Cain } 21366b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 21373a2d0424SChris Cain { 21386b9ac4f2SChris Cain return PowerMode::OEM; 21396b9ac4f2SChris Cain } 21406b9ac4f2SChris Cain // Any other values would be invalid 21416b9ac4f2SChris Cain BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString); 21426b9ac4f2SChris Cain return PowerMode::Invalid; 21436b9ac4f2SChris Cain } 21446b9ac4f2SChris Cain 21456b9ac4f2SChris Cain inline void 21466b9ac4f2SChris Cain afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 21476b9ac4f2SChris Cain const boost::system::error_code& ec, 21486b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) 21496b9ac4f2SChris Cain { 21506b9ac4f2SChris Cain if (ec) 21516b9ac4f2SChris Cain { 21526b9ac4f2SChris Cain BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec); 21536b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21546b9ac4f2SChris Cain return; 21556b9ac4f2SChris Cain } 21566b9ac4f2SChris Cain 21576b9ac4f2SChris Cain std::string powerMode; 21586b9ac4f2SChris Cain const std::vector<std::string>* allowedModes = nullptr; 21596b9ac4f2SChris Cain const bool success = sdbusplus::unpackPropertiesNoThrow( 21606b9ac4f2SChris Cain dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode, 21616b9ac4f2SChris Cain "AllowedPowerModes", allowedModes); 21626b9ac4f2SChris Cain 21636b9ac4f2SChris Cain if (!success) 21646b9ac4f2SChris Cain { 21656b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21666b9ac4f2SChris Cain return; 21676b9ac4f2SChris Cain } 21686b9ac4f2SChris Cain 21696b9ac4f2SChris Cain nlohmann::json::array_t modeList; 21706b9ac4f2SChris Cain if (allowedModes == nullptr) 21716b9ac4f2SChris Cain { 21726b9ac4f2SChris Cain modeList.emplace_back("Static"); 21736b9ac4f2SChris Cain modeList.emplace_back("MaximumPerformance"); 21746b9ac4f2SChris Cain modeList.emplace_back("PowerSaving"); 21753a2d0424SChris Cain } 21763a2d0424SChris Cain else 21773a2d0424SChris Cain { 21786b9ac4f2SChris Cain for (const auto& aMode : *allowedModes) 21796b9ac4f2SChris Cain { 21806b9ac4f2SChris Cain computer_system::PowerMode modeValue = 21816b9ac4f2SChris Cain translatePowerModeString(aMode); 21826b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21836b9ac4f2SChris Cain { 2184ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21856b9ac4f2SChris Cain continue; 21866b9ac4f2SChris Cain } 21876b9ac4f2SChris Cain modeList.emplace_back(modeValue); 21883a2d0424SChris Cain } 21893a2d0424SChris Cain } 21906b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList; 21913a2d0424SChris Cain 21926b9ac4f2SChris Cain BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode); 21936b9ac4f2SChris Cain const computer_system::PowerMode modeValue = 21946b9ac4f2SChris Cain translatePowerModeString(powerMode); 21956b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21966b9ac4f2SChris Cain { 21976b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21986b9ac4f2SChris Cain return; 21996b9ac4f2SChris Cain } 22006b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode"] = modeValue; 22016b9ac4f2SChris Cain } 22023a2d0424SChris Cain /** 22033a2d0424SChris Cain * @brief Retrieves system power mode 22043a2d0424SChris Cain * 2205ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22063a2d0424SChris Cain * 22073a2d0424SChris Cain * @return None. 22083a2d0424SChris Cain */ 2209ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 22103a2d0424SChris Cain { 221162598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 22123a2d0424SChris Cain 22133a2d0424SChris Cain // Get Power Mode object path: 2214e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2215e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2216e99073f5SGeorge Liu dbus::utility::getSubTree( 2217e99073f5SGeorge Liu "/", 0, interfaces, 2218ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2219b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22203a2d0424SChris Cain if (ec) 22213a2d0424SChris Cain { 222262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}", 222362598e31SEd Tanous ec); 22243a2d0424SChris Cain // This is an optional D-Bus object so just return if 22253a2d0424SChris Cain // error occurs 22263a2d0424SChris Cain return; 22273a2d0424SChris Cain } 22283a2d0424SChris Cain if (subtree.empty()) 22293a2d0424SChris Cain { 22303a2d0424SChris Cain // As noted above, this is an optional interface so just return 22313a2d0424SChris Cain // if there is no instance found 22323a2d0424SChris Cain return; 22333a2d0424SChris Cain } 22343a2d0424SChris Cain if (subtree.size() > 1) 22353a2d0424SChris Cain { 22363a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22373a2d0424SChris Cain // error 223862598e31SEd Tanous BMCWEB_LOG_DEBUG( 223962598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 224062598e31SEd Tanous subtree.size()); 2241ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22423a2d0424SChris Cain return; 22433a2d0424SChris Cain } 22443a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22453a2d0424SChris Cain { 224662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2247ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22483a2d0424SChris Cain return; 22493a2d0424SChris Cain } 22503a2d0424SChris Cain const std::string& path = subtree[0].first; 22513a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22523a2d0424SChris Cain if (service.empty()) 22533a2d0424SChris Cain { 225462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2255ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22563a2d0424SChris Cain return; 22573a2d0424SChris Cain } 22586b9ac4f2SChris Cain 22596b9ac4f2SChris Cain // Valid Power Mode object found, now read the mode properties 22606b9ac4f2SChris Cain sdbusplus::asio::getAllProperties( 22611e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 22626b9ac4f2SChris Cain "xyz.openbmc_project.Control.Power.Mode", 2263ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 22646b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 22656b9ac4f2SChris Cain afterGetPowerMode(asyncResp, ec2, properties); 22661e1e598dSJonathan Doman }); 2267e99073f5SGeorge Liu }); 22683a2d0424SChris Cain } 22693a2d0424SChris Cain 22703a2d0424SChris Cain /** 22713a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 22723a2d0424SChris Cain * name associated with that string 22733a2d0424SChris Cain * 2274ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2275b6655101SChris Cain * @param[in] modeValue String representing the desired PowerMode 22763a2d0424SChris Cain * 22773a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22783a2d0424SChris Cain */ 22793a2d0424SChris Cain inline std::string 2280ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2281b6655101SChris Cain const nlohmann::json& modeValue) 22823a2d0424SChris Cain { 2283b6655101SChris Cain using PowerMode = computer_system::PowerMode; 22843a2d0424SChris Cain std::string mode; 22853a2d0424SChris Cain 2286b6655101SChris Cain if (modeValue == PowerMode::Static) 22873a2d0424SChris Cain { 22883a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22893a2d0424SChris Cain } 2290b6655101SChris Cain else if (modeValue == PowerMode::MaximumPerformance) 22913a2d0424SChris Cain { 22920fda0f12SGeorge Liu mode = 22930fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 22943a2d0424SChris Cain } 2295b6655101SChris Cain else if (modeValue == PowerMode::PowerSaving) 22963a2d0424SChris Cain { 22973a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22983a2d0424SChris Cain } 2299b6655101SChris Cain else if (modeValue == PowerMode::BalancedPerformance) 2300b6655101SChris Cain { 2301b6655101SChris Cain mode = 2302b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance"; 2303b6655101SChris Cain } 2304b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPerformance) 2305b6655101SChris Cain { 2306b6655101SChris Cain mode = 2307b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance"; 2308b6655101SChris Cain } 2309b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPower) 2310b6655101SChris Cain { 2311b6655101SChris Cain mode = 2312b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower"; 2313b6655101SChris Cain } 23143a2d0424SChris Cain else 23153a2d0424SChris Cain { 2316b6655101SChris Cain messages::propertyValueNotInList(asyncResp->res, modeValue.dump(), 2317ac106bf6SEd Tanous "PowerMode"); 23183a2d0424SChris Cain } 23193a2d0424SChris Cain return mode; 23203a2d0424SChris Cain } 23213a2d0424SChris Cain 23223a2d0424SChris Cain /** 23233a2d0424SChris Cain * @brief Sets system power mode. 23243a2d0424SChris Cain * 2325ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 23263a2d0424SChris Cain * @param[in] pmode System power mode from request. 23273a2d0424SChris Cain * 23283a2d0424SChris Cain * @return None. 23293a2d0424SChris Cain */ 2330ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 23313a2d0424SChris Cain const std::string& pmode) 23323a2d0424SChris Cain { 233362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 23343a2d0424SChris Cain 2335ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 23363a2d0424SChris Cain if (powerMode.empty()) 23373a2d0424SChris Cain { 23383a2d0424SChris Cain return; 23393a2d0424SChris Cain } 23403a2d0424SChris Cain 23413a2d0424SChris Cain // Get Power Mode object path: 2342e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2343e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2344e99073f5SGeorge Liu dbus::utility::getSubTree( 2345e99073f5SGeorge Liu "/", 0, interfaces, 2346ac106bf6SEd Tanous [asyncResp, 2347e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2348b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23493a2d0424SChris Cain if (ec) 23503a2d0424SChris Cain { 2351b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}", 235262598e31SEd Tanous ec); 23533a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2354ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23553a2d0424SChris Cain return; 23563a2d0424SChris Cain } 23573a2d0424SChris Cain if (subtree.empty()) 23583a2d0424SChris Cain { 23593a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2360ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 23613a2d0424SChris Cain "PowerMode"); 23623a2d0424SChris Cain return; 23633a2d0424SChris Cain } 23643a2d0424SChris Cain if (subtree.size() > 1) 23653a2d0424SChris Cain { 23663a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23673a2d0424SChris Cain // error 236862598e31SEd Tanous BMCWEB_LOG_DEBUG( 236962598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 237062598e31SEd Tanous subtree.size()); 2371ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23723a2d0424SChris Cain return; 23733a2d0424SChris Cain } 23743a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23753a2d0424SChris Cain { 237662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2377ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23783a2d0424SChris Cain return; 23793a2d0424SChris Cain } 23803a2d0424SChris Cain const std::string& path = subtree[0].first; 23813a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23823a2d0424SChris Cain if (service.empty()) 23833a2d0424SChris Cain { 238462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2385ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23863a2d0424SChris Cain return; 23873a2d0424SChris Cain } 23883a2d0424SChris Cain 238962598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 23903a2d0424SChris Cain 23913a2d0424SChris Cain // Set the Power Mode property 23929ae226faSGeorge Liu sdbusplus::asio::setProperty( 23939ae226faSGeorge Liu *crow::connections::systemBus, service, path, 23949ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode, 2395ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 23968a592810SEd Tanous if (ec2) 23973a2d0424SChris Cain { 2398b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2399ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24003a2d0424SChris Cain return; 24013a2d0424SChris Cain } 24029ae226faSGeorge Liu }); 2403e99073f5SGeorge Liu }); 24043a2d0424SChris Cain } 24053a2d0424SChris Cain 24063a2d0424SChris Cain /** 240751709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 240851709ffdSYong Li * 240951709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 241051709ffdSYong Li * 241151709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 241251709ffdSYong Li * translation cannot be done, returns an empty string. 241351709ffdSYong Li */ 241423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 241551709ffdSYong Li { 241651709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 241751709ffdSYong Li { 241851709ffdSYong Li return "None"; 241951709ffdSYong Li } 24203174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 242151709ffdSYong Li { 242251709ffdSYong Li return "ResetSystem"; 242351709ffdSYong Li } 24243174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 242551709ffdSYong Li { 242651709ffdSYong Li return "PowerDown"; 242751709ffdSYong Li } 24283174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 242951709ffdSYong Li { 243051709ffdSYong Li return "PowerCycle"; 243151709ffdSYong Li } 243251709ffdSYong Li 243351709ffdSYong Li return ""; 243451709ffdSYong Li } 243551709ffdSYong Li 243651709ffdSYong Li /** 2437c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2438c45f0082SYong Li * 2439c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2440c45f0082SYong Li * 2441c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2442c45f0082SYong Li *If translation cannot be done, returns an empty string. 2443c45f0082SYong Li */ 2444c45f0082SYong Li 244523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2446c45f0082SYong Li { 2447c45f0082SYong Li if (rfAction == "None") 2448c45f0082SYong Li { 2449c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2450c45f0082SYong Li } 24513174e4dfSEd Tanous if (rfAction == "PowerCycle") 2452c45f0082SYong Li { 2453c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2454c45f0082SYong Li } 24553174e4dfSEd Tanous if (rfAction == "PowerDown") 2456c45f0082SYong Li { 2457c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2458c45f0082SYong Li } 24593174e4dfSEd Tanous if (rfAction == "ResetSystem") 2460c45f0082SYong Li { 2461c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2462c45f0082SYong Li } 2463c45f0082SYong Li 2464c45f0082SYong Li return ""; 2465c45f0082SYong Li } 2466c45f0082SYong Li 2467c45f0082SYong Li /** 246851709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 246951709ffdSYong Li * 2470ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 247151709ffdSYong Li * 247251709ffdSYong Li * @return None. 247351709ffdSYong Li */ 24748d1b46d7Szhanghch05 inline void 2475ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 247651709ffdSYong Li { 247762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2478bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2479bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2480bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2481bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2482ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2483b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 248451709ffdSYong Li if (ec) 248551709ffdSYong Li { 248651709ffdSYong Li // watchdog service is stopped 248762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 248851709ffdSYong Li return; 248951709ffdSYong Li } 249051709ffdSYong Li 249162598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 249251709ffdSYong Li 249351709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2494ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 249551709ffdSYong Li 249651709ffdSYong Li // watchdog service is running/enabled 249751709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 249851709ffdSYong Li 2499bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2500bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 250151709ffdSYong Li 2502bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2503bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2504bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2505bc1d29deSKrzysztof Grobelny 2506bc1d29deSKrzysztof Grobelny if (!success) 250751709ffdSYong Li { 2508ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2509601af5edSChicago Duan return; 251051709ffdSYong Li } 251151709ffdSYong Li 2512bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 251351709ffdSYong Li { 2514bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 251551709ffdSYong Li } 251651709ffdSYong Li 2517bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2518bc1d29deSKrzysztof Grobelny { 2519bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 252051709ffdSYong Li if (action.empty()) 252151709ffdSYong Li { 2522ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2523601af5edSChicago Duan return; 252451709ffdSYong Li } 252551709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 252651709ffdSYong Li } 2527bc1d29deSKrzysztof Grobelny }); 252851709ffdSYong Li } 252951709ffdSYong Li 253051709ffdSYong Li /** 2531c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2532c45f0082SYong Li * 2533ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2534c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2535c45f0082SYong Li * RF request. 2536c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2537c45f0082SYong Li * 2538c45f0082SYong Li * @return None. 2539c45f0082SYong Li */ 2540ac106bf6SEd Tanous inline void 2541ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2542c45f0082SYong Li const std::optional<bool> wdtEnable, 2543c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2544c45f0082SYong Li { 254562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2546c45f0082SYong Li 2547c45f0082SYong Li if (wdtTimeOutAction) 2548c45f0082SYong Li { 2549c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2550c45f0082SYong Li // check if TimeOut Action is Valid 2551c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2552c45f0082SYong Li { 255362598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 255462598e31SEd Tanous *wdtTimeOutAction); 2555ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2556c45f0082SYong Li "TimeoutAction"); 2557c45f0082SYong Li return; 2558c45f0082SYong Li } 2559c45f0082SYong Li 25609ae226faSGeorge Liu sdbusplus::asio::setProperty( 25619ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25629ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25639ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 25649ae226faSGeorge Liu wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) { 2565c45f0082SYong Li if (ec) 2566c45f0082SYong Li { 2567b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2568ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2569c45f0082SYong Li return; 2570c45f0082SYong Li } 25719ae226faSGeorge Liu }); 2572c45f0082SYong Li } 2573c45f0082SYong Li 2574c45f0082SYong Li if (wdtEnable) 2575c45f0082SYong Li { 25769ae226faSGeorge Liu sdbusplus::asio::setProperty( 25779ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25789ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25799ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable, 2580ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2581c45f0082SYong Li if (ec) 2582c45f0082SYong Li { 2583b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2584ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2585c45f0082SYong Li return; 2586c45f0082SYong Li } 25879ae226faSGeorge Liu }); 2588c45f0082SYong Li } 2589c45f0082SYong Li } 2590c45f0082SYong Li 259137bbf98cSChris Cain /** 259237bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 259337bbf98cSChris Cain * 2594ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 259537bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 259637bbf98cSChris Cain * 259737bbf98cSChris Cain * @return true if successful 259837bbf98cSChris Cain */ 25991e5b7c88SJiaqing Zhao inline bool 2600ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 26011e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 260237bbf98cSChris Cain { 2603bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2604bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2605bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2606bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2607bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2608bc1d29deSKrzysztof Grobelny 2609bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2610bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 26112661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 26122661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 26132661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2614bc1d29deSKrzysztof Grobelny 2615bc1d29deSKrzysztof Grobelny if (!success) 261637bbf98cSChris Cain { 261737bbf98cSChris Cain return false; 261837bbf98cSChris Cain } 2619bc1d29deSKrzysztof Grobelny 2620bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 262137bbf98cSChris Cain { 2622ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 262337bbf98cSChris Cain } 2624bc1d29deSKrzysztof Grobelny 2625bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 262637bbf98cSChris Cain { 2627ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2628bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 262937bbf98cSChris Cain } 2630bc1d29deSKrzysztof Grobelny 2631bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2632bc1d29deSKrzysztof Grobelny { 2633bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2634ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 263537bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 263637bbf98cSChris Cain .count(); 263737bbf98cSChris Cain } 2638bc1d29deSKrzysztof Grobelny 2639bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 264037bbf98cSChris Cain { 2641ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2642bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 264337bbf98cSChris Cain } 2644bc1d29deSKrzysztof Grobelny 2645bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 264637bbf98cSChris Cain { 2647bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2648ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 264937bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 265037bbf98cSChris Cain .count(); 265137bbf98cSChris Cain } 265237bbf98cSChris Cain 265337bbf98cSChris Cain return true; 265437bbf98cSChris Cain } 265537bbf98cSChris Cain 265637bbf98cSChris Cain /** 265737bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 265837bbf98cSChris Cain * 2659ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 266037bbf98cSChris Cain * 266137bbf98cSChris Cain * @return None. 266237bbf98cSChris Cain */ 2663ac106bf6SEd Tanous inline void 2664ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 266537bbf98cSChris Cain { 266662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 266737bbf98cSChris Cain 266837bbf98cSChris Cain // Get IdlePowerSaver object path: 2669e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2670e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2671e99073f5SGeorge Liu dbus::utility::getSubTree( 2672e99073f5SGeorge Liu "/", 0, interfaces, 2673ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2674b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 267537bbf98cSChris Cain if (ec) 267637bbf98cSChris Cain { 2677b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 267862598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 267962598e31SEd Tanous ec); 2680ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268137bbf98cSChris Cain return; 268237bbf98cSChris Cain } 268337bbf98cSChris Cain if (subtree.empty()) 268437bbf98cSChris Cain { 268537bbf98cSChris Cain // This is an optional interface so just return 268637bbf98cSChris Cain // if there is no instance found 268762598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 268837bbf98cSChris Cain return; 268937bbf98cSChris Cain } 269037bbf98cSChris Cain if (subtree.size() > 1) 269137bbf98cSChris Cain { 269237bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 269337bbf98cSChris Cain // is an error 269462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 269562598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 269662598e31SEd Tanous subtree.size()); 2697ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269837bbf98cSChris Cain return; 269937bbf98cSChris Cain } 270037bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 270137bbf98cSChris Cain { 270262598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2703ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270437bbf98cSChris Cain return; 270537bbf98cSChris Cain } 270637bbf98cSChris Cain const std::string& path = subtree[0].first; 270737bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 270837bbf98cSChris Cain if (service.empty()) 270937bbf98cSChris Cain { 271062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2711ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271237bbf98cSChris Cain return; 271337bbf98cSChris Cain } 271437bbf98cSChris Cain 271537bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2716bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2717bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2718bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2719ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 27201e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 27218a592810SEd Tanous if (ec2) 272237bbf98cSChris Cain { 272362598e31SEd Tanous BMCWEB_LOG_ERROR( 272462598e31SEd Tanous "DBUS response error on IdlePowerSaver GetAll: {}", ec2); 2725ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272637bbf98cSChris Cain return; 272737bbf98cSChris Cain } 272837bbf98cSChris Cain 2729ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 273037bbf98cSChris Cain { 2731ac106bf6SEd Tanous messages::internalError(asyncResp->res); 273237bbf98cSChris Cain return; 273337bbf98cSChris Cain } 2734bc1d29deSKrzysztof Grobelny }); 2735e99073f5SGeorge Liu }); 273637bbf98cSChris Cain 273762598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 273837bbf98cSChris Cain } 273937bbf98cSChris Cain 274037bbf98cSChris Cain /** 274137bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 274237bbf98cSChris Cain * 2743ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 274437bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 274537bbf98cSChris Cain * RF request. 274637bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 274737bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 274837bbf98cSChris Cain * before entering idle state. 274937bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 275037bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 275137bbf98cSChris Cain * before exiting idle state 275237bbf98cSChris Cain * 275337bbf98cSChris Cain * @return None. 275437bbf98cSChris Cain */ 2755ac106bf6SEd Tanous inline void 2756ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 275737bbf98cSChris Cain const std::optional<bool> ipsEnable, 275837bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 275937bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 276037bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 276137bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 276237bbf98cSChris Cain { 276362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 276437bbf98cSChris Cain 276537bbf98cSChris Cain // Get IdlePowerSaver object path: 2766e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2767e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2768e99073f5SGeorge Liu dbus::utility::getSubTree( 2769e99073f5SGeorge Liu "/", 0, interfaces, 2770ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2771e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2772b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 277337bbf98cSChris Cain if (ec) 277437bbf98cSChris Cain { 2775b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 277662598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 277762598e31SEd Tanous ec); 2778ac106bf6SEd Tanous messages::internalError(asyncResp->res); 277937bbf98cSChris Cain return; 278037bbf98cSChris Cain } 278137bbf98cSChris Cain if (subtree.empty()) 278237bbf98cSChris Cain { 278337bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2784ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 278537bbf98cSChris Cain "IdlePowerSaver"); 278637bbf98cSChris Cain return; 278737bbf98cSChris Cain } 278837bbf98cSChris Cain if (subtree.size() > 1) 278937bbf98cSChris Cain { 279037bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 279137bbf98cSChris Cain // is an error 279262598e31SEd Tanous BMCWEB_LOG_DEBUG( 279362598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 279462598e31SEd Tanous subtree.size()); 2795ac106bf6SEd Tanous messages::internalError(asyncResp->res); 279637bbf98cSChris Cain return; 279737bbf98cSChris Cain } 279837bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 279937bbf98cSChris Cain { 280062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2801ac106bf6SEd Tanous messages::internalError(asyncResp->res); 280237bbf98cSChris Cain return; 280337bbf98cSChris Cain } 280437bbf98cSChris Cain const std::string& path = subtree[0].first; 280537bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 280637bbf98cSChris Cain if (service.empty()) 280737bbf98cSChris Cain { 280862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2809ac106bf6SEd Tanous messages::internalError(asyncResp->res); 281037bbf98cSChris Cain return; 281137bbf98cSChris Cain } 281237bbf98cSChris Cain 281337bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 281437bbf98cSChris Cain // need to be updated 281537bbf98cSChris Cain 281637bbf98cSChris Cain if (ipsEnable) 281737bbf98cSChris Cain { 28189ae226faSGeorge Liu sdbusplus::asio::setProperty( 28199ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28209ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 28219ae226faSGeorge Liu *ipsEnable, [asyncResp](const boost::system::error_code& ec2) { 28228a592810SEd Tanous if (ec2) 282337bbf98cSChris Cain { 2824b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2825ac106bf6SEd Tanous messages::internalError(asyncResp->res); 282637bbf98cSChris Cain return; 282737bbf98cSChris Cain } 28289ae226faSGeorge Liu }); 282937bbf98cSChris Cain } 283037bbf98cSChris Cain if (ipsEnterUtil) 283137bbf98cSChris Cain { 28329ae226faSGeorge Liu sdbusplus::asio::setProperty( 28339ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28349ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28359ae226faSGeorge Liu "EnterUtilizationPercent", *ipsEnterUtil, 2836ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28378a592810SEd Tanous if (ec2) 283837bbf98cSChris Cain { 2839b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2840ac106bf6SEd Tanous messages::internalError(asyncResp->res); 284137bbf98cSChris Cain return; 284237bbf98cSChris Cain } 28439ae226faSGeorge Liu }); 284437bbf98cSChris Cain } 284537bbf98cSChris Cain if (ipsEnterTime) 284637bbf98cSChris Cain { 284737bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 284837bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 28499ae226faSGeorge Liu sdbusplus::asio::setProperty( 28509ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28519ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28529ae226faSGeorge Liu "EnterDwellTime", timeMilliseconds, 2853ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28548a592810SEd Tanous if (ec2) 285537bbf98cSChris Cain { 2856b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2857ac106bf6SEd Tanous messages::internalError(asyncResp->res); 285837bbf98cSChris Cain return; 285937bbf98cSChris Cain } 28609ae226faSGeorge Liu }); 286137bbf98cSChris Cain } 286237bbf98cSChris Cain if (ipsExitUtil) 286337bbf98cSChris Cain { 28649ae226faSGeorge Liu sdbusplus::asio::setProperty( 28659ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28669ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28679ae226faSGeorge Liu "ExitUtilizationPercent", *ipsExitUtil, 2868ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28698a592810SEd Tanous if (ec2) 287037bbf98cSChris Cain { 2871b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2872ac106bf6SEd Tanous messages::internalError(asyncResp->res); 287337bbf98cSChris Cain return; 287437bbf98cSChris Cain } 28759ae226faSGeorge Liu }); 287637bbf98cSChris Cain } 287737bbf98cSChris Cain if (ipsExitTime) 287837bbf98cSChris Cain { 287937bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 288037bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 28819ae226faSGeorge Liu sdbusplus::asio::setProperty( 28829ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28839ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28849ae226faSGeorge Liu "ExitDwellTime", timeMilliseconds, 2885ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28868a592810SEd Tanous if (ec2) 288737bbf98cSChris Cain { 2888b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2889ac106bf6SEd Tanous messages::internalError(asyncResp->res); 289037bbf98cSChris Cain return; 289137bbf98cSChris Cain } 28929ae226faSGeorge Liu }); 289337bbf98cSChris Cain } 2894e99073f5SGeorge Liu }); 289537bbf98cSChris Cain 289662598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 289737bbf98cSChris Cain } 289837bbf98cSChris Cain 2899c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2900dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2901dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2902dd60b9edSEd Tanous { 2903dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2904dd60b9edSEd Tanous { 2905dd60b9edSEd Tanous return; 2906dd60b9edSEd Tanous } 2907dd60b9edSEd Tanous asyncResp->res.addHeader( 2908dd60b9edSEd Tanous boost::beast::http::field::link, 2909dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2910dd60b9edSEd Tanous } 2911dd60b9edSEd Tanous 2912c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2913c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2914c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29151abe55efSEd Tanous { 29163ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2917f4c99e70SEd Tanous { 2918f4c99e70SEd Tanous return; 2919f4c99e70SEd Tanous } 2920dd60b9edSEd Tanous 2921dd60b9edSEd Tanous asyncResp->res.addHeader( 2922dd60b9edSEd Tanous boost::beast::http::field::link, 2923dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 29248d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 29250f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 29268d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 29278d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2928462023adSSunitha Harish 29297f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 29307f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 29317f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 29327f3e84a1SEd Tanous { 29337f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 29347f3e84a1SEd Tanous // Option currently returns no systems. TBD 29357f3e84a1SEd Tanous return; 29367f3e84a1SEd Tanous } 29377f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 29387f3e84a1SEd Tanous nlohmann::json::object_t system; 29397f3e84a1SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 29407f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 29411e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2942002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 29431e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2944002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 29455e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 29461e1e598dSJonathan Doman const std::string& /*hostName*/) { 29477f3e84a1SEd Tanous if (ec2) 2948462023adSSunitha Harish { 29497f3e84a1SEd Tanous return; 29507f3e84a1SEd Tanous } 29517f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 29527f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 29537f3e84a1SEd Tanous { 295462598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 29557f3e84a1SEd Tanous return; 29567f3e84a1SEd Tanous } 29577f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 29587f3e84a1SEd Tanous if (count == nullptr) 29597f3e84a1SEd Tanous { 296062598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 29617f3e84a1SEd Tanous return; 29627f3e84a1SEd Tanous } 29637f3e84a1SEd Tanous *count = *count + 1; 296462598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 29657f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 29661476687dSEd Tanous nlohmann::json::object_t hypervisor; 2967002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 29687f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 29691e1e598dSJonathan Doman }); 2970c1e219d5SEd Tanous } 2971c1e219d5SEd Tanous 2972c1e219d5SEd Tanous /** 29737e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 29747e860f15SJohn Edward Broadbent */ 29754f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29767e860f15SJohn Edward Broadbent { 297789492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 297889492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 297989492a15SPatrick Williams constexpr const char* interfaceName = 29807e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 298189492a15SPatrick Williams constexpr const char* method = "NMI"; 29827e860f15SJohn Edward Broadbent 29837e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 29845e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 29857e860f15SJohn Edward Broadbent if (ec) 29867e860f15SJohn Edward Broadbent { 298762598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 29887e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 29897e860f15SJohn Edward Broadbent return; 29907e860f15SJohn Edward Broadbent } 29917e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 29927e860f15SJohn Edward Broadbent }, 29937e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 29947e860f15SJohn Edward Broadbent } 2995c5b2abe0SLewanczyk, Dawid 2996c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2997c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 29987f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2999c1e219d5SEd Tanous const std::string& systemName) 3000c1e219d5SEd Tanous { 30013ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 300245ca1b86SEd Tanous { 300345ca1b86SEd Tanous return; 300445ca1b86SEd Tanous } 3005c1e219d5SEd Tanous if (systemName != "system") 3006c1e219d5SEd Tanous { 3007c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3008c1e219d5SEd Tanous systemName); 3009c1e219d5SEd Tanous return; 3010c1e219d5SEd Tanous } 30117f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 30127f3e84a1SEd Tanous { 30137f3e84a1SEd Tanous // Option currently returns no systems. TBD 30147f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3015c1e219d5SEd Tanous systemName); 30167f3e84a1SEd Tanous return; 30177f3e84a1SEd Tanous } 30189712f8acSEd Tanous std::string resetType; 3019c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 3020cc340dd9SEd Tanous { 3021cc340dd9SEd Tanous return; 3022cc340dd9SEd Tanous } 3023cc340dd9SEd Tanous 3024d22c8396SJason M. Bills // Get the command and host vs. chassis 3025cc340dd9SEd Tanous std::string command; 3026543f4400SEd Tanous bool hostCommand = true; 3027d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 3028cc340dd9SEd Tanous { 3029cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 3030d22c8396SJason M. Bills hostCommand = true; 3031d22c8396SJason M. Bills } 3032d22c8396SJason M. Bills else if (resetType == "ForceOff") 3033d22c8396SJason M. Bills { 3034d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 3035d22c8396SJason M. Bills hostCommand = false; 3036d22c8396SJason M. Bills } 3037d22c8396SJason M. Bills else if (resetType == "ForceRestart") 3038d22c8396SJason M. Bills { 3039c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 304086a0851aSJason M. Bills hostCommand = true; 3041cc340dd9SEd Tanous } 30429712f8acSEd Tanous else if (resetType == "GracefulShutdown") 3043cc340dd9SEd Tanous { 3044cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 3045d22c8396SJason M. Bills hostCommand = true; 3046cc340dd9SEd Tanous } 30479712f8acSEd Tanous else if (resetType == "GracefulRestart") 3048cc340dd9SEd Tanous { 30490fda0f12SGeorge Liu command = 30500fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 3051d22c8396SJason M. Bills hostCommand = true; 3052d22c8396SJason M. Bills } 3053d22c8396SJason M. Bills else if (resetType == "PowerCycle") 3054d22c8396SJason M. Bills { 305586a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 305686a0851aSJason M. Bills hostCommand = true; 3057cc340dd9SEd Tanous } 3058bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 3059bfd5b826SLakshminarayana R. Kammath { 3060bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 3061bfd5b826SLakshminarayana R. Kammath return; 3062bfd5b826SLakshminarayana R. Kammath } 3063cc340dd9SEd Tanous else 3064cc340dd9SEd Tanous { 3065c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 3066cc340dd9SEd Tanous return; 3067cc340dd9SEd Tanous } 3068d02aad39SEd Tanous sdbusplus::message::object_path statePath("/xyz/openbmc_project/state"); 3069cc340dd9SEd Tanous 3070d22c8396SJason M. Bills if (hostCommand) 3071d22c8396SJason M. Bills { 3072d02aad39SEd Tanous setDbusProperty(asyncResp, "xyz.openbmc_project.State.Host", 3073d02aad39SEd Tanous statePath / "host0", "xyz.openbmc_project.State.Host", 3074d02aad39SEd Tanous "RequestedHostTransition", "Reset", command); 3075cc340dd9SEd Tanous } 3076d22c8396SJason M. Bills else 3077d22c8396SJason M. Bills { 3078d02aad39SEd Tanous setDbusProperty(asyncResp, "xyz.openbmc_project.State.Chassis", 3079d02aad39SEd Tanous statePath / "chassis0", 3080d02aad39SEd Tanous "xyz.openbmc_project.State.Chassis", 3081d02aad39SEd Tanous "RequestedPowerTransition", "Reset", command); 3082d22c8396SJason M. Bills } 3083d22c8396SJason M. Bills } 3084cc340dd9SEd Tanous 3085c1e219d5SEd Tanous inline void handleComputerSystemHead( 3086dd60b9edSEd Tanous App& app, const crow::Request& req, 30877f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 30887f3e84a1SEd Tanous const std::string& /*systemName*/) 3089dd60b9edSEd Tanous { 3090dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3091dd60b9edSEd Tanous { 3092dd60b9edSEd Tanous return; 3093dd60b9edSEd Tanous } 3094dd60b9edSEd Tanous 3095dd60b9edSEd Tanous asyncResp->res.addHeader( 3096dd60b9edSEd Tanous boost::beast::http::field::link, 3097dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3098dd60b9edSEd Tanous } 3099dd60b9edSEd Tanous 31005c3e9272SAbhishek Patel inline void afterPortRequest( 31015c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31025c3e9272SAbhishek Patel const boost::system::error_code& ec, 31035c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 31045c3e9272SAbhishek Patel { 31055c3e9272SAbhishek Patel if (ec) 31065c3e9272SAbhishek Patel { 3107b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 31085c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31095c3e9272SAbhishek Patel return; 31105c3e9272SAbhishek Patel } 31115c3e9272SAbhishek Patel for (const auto& data : socketData) 31125c3e9272SAbhishek Patel { 31135c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 31145c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 31155c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 31165c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 31175c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 31185c3e9272SAbhishek Patel // need to retrieve port number for 31195c3e9272SAbhishek Patel // obmc-console-ssh service 31205c3e9272SAbhishek Patel if (protocolName == "SSH") 31215c3e9272SAbhishek Patel { 31225c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 312381c4e330SEd Tanous const boost::system::error_code& ec1, 31245c3e9272SAbhishek Patel int portNumber) { 31255c3e9272SAbhishek Patel if (ec1) 31265c3e9272SAbhishek Patel { 3127b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 31285c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31295c3e9272SAbhishek Patel return; 31305c3e9272SAbhishek Patel } 31315c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 31325c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 31335c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 31345c3e9272SAbhishek Patel }); 31355c3e9272SAbhishek Patel } 31365c3e9272SAbhishek Patel } 31375c3e9272SAbhishek Patel } 3138c1e219d5SEd Tanous 3139c1e219d5SEd Tanous inline void 3140c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 314122d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3142c1e219d5SEd Tanous const std::string& systemName) 3143c1e219d5SEd Tanous { 31443ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 314545ca1b86SEd Tanous { 314645ca1b86SEd Tanous return; 314745ca1b86SEd Tanous } 3148746b56f3SAsmitha Karunanithi 31497f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 31507f3e84a1SEd Tanous { 31517f3e84a1SEd Tanous // Option currently returns no systems. TBD 31527f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31537f3e84a1SEd Tanous systemName); 31547f3e84a1SEd Tanous return; 31557f3e84a1SEd Tanous } 31567f3e84a1SEd Tanous 3157746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3158746b56f3SAsmitha Karunanithi { 3159746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3160746b56f3SAsmitha Karunanithi return; 3161746b56f3SAsmitha Karunanithi } 3162746b56f3SAsmitha Karunanithi 316322d268cbSEd Tanous if (systemName != "system") 316422d268cbSEd Tanous { 316522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 316622d268cbSEd Tanous systemName); 316722d268cbSEd Tanous return; 316822d268cbSEd Tanous } 3169dd60b9edSEd Tanous asyncResp->res.addHeader( 3170dd60b9edSEd Tanous boost::beast::http::field::link, 3171dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 31728d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3173b6655101SChris Cain "#ComputerSystem.v1_22_0.ComputerSystem"; 31748d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 31758d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 31768d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 31778d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 31788d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 3179cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3180dfb2b408SPriyanga Ramasamy double(0); 3181002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 318204a258f4SEd Tanous 31831476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 31841476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 31851476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 31861476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 31871476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 31881476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 31893179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 31903179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3191029573d4SEd Tanous 3192002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 31931476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 3194c1e219d5SEd Tanous asyncResp->res 3195c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 31961476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3197c5b2abe0SLewanczyk, Dawid 31981476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 31991476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 32001476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 32011476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3202c4bf6374SJason M. Bills 32031476687dSEd Tanous nlohmann::json::array_t managedBy; 32041476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 32051476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3206002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 32071476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 32081476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 32090e8ac5e7SGunnar Mills 32100e8ac5e7SGunnar Mills // Fill in SerialConsole info 3211002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3212c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 32131476687dSEd Tanous 3214c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 32151476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3216c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 32171476687dSEd Tanous "Press ~. to exit console"; 32185c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 32195c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 32200e8ac5e7SGunnar Mills 32210e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 32220e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3223002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3224c1e219d5SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4; 3225613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3226613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 32271476687dSEd Tanous 32280e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 322913451e39SWilly Tu 323013451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 323113451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 323213451e39SWilly Tu { 32337a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3234b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 32352ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3236e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3237e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3238b49ac873SJames Feist 32397a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 32407a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 32417a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3242914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3243b49ac873SJames Feist if (ec) 3244b49ac873SJames Feist { 3245b49ac873SJames Feist // no inventory 3246b49ac873SJames Feist return; 3247b49ac873SJames Feist } 3248b49ac873SJames Feist 3249914e2d5dSEd Tanous health->inventory = resp; 32507a1dbc48SGeorge Liu }); 3251b49ac873SJames Feist health->populate(); 325213451e39SWilly Tu } 3253b49ac873SJames Feist 3254002d39b4SEd Tanous getMainChassisId(asyncResp, 3255002d39b4SEd Tanous [](const std::string& chassisId, 32568d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3257b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3258b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3259ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3260ef4c65b7SEd Tanous chassisId); 3261002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3262c5d03ff4SJennifer Lee }); 3263a3002228SAppaRao Puli 326459a17e4fSGeorge Liu getSystemLocationIndicatorActive(asyncResp); 32659f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3266a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 3267*51bd2d8aSGunnar Mills getComputerSystem(asyncResp); 32686c34de48SEd Tanous getHostState(asyncResp); 3269491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3270978b8803SAndrew Geissler getBootProgress(asyncResp); 3271b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 327270c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 327370c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 327451709ffdSYong Li getHostWatchdogTimer(asyncResp); 3275c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 32769dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3277797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3278c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3279a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3280a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3281a6349918SAppaRao Puli #endif 32821981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 32833a2d0424SChris Cain getPowerMode(asyncResp); 328437bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3285c1e219d5SEd Tanous } 3286550a6bf8SJiaqing Zhao 3287c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3288c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 328922d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3290c1e219d5SEd Tanous const std::string& systemName) 3291c1e219d5SEd Tanous { 32923ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 329345ca1b86SEd Tanous { 329445ca1b86SEd Tanous return; 329545ca1b86SEd Tanous } 32967f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 32977f3e84a1SEd Tanous { 32987f3e84a1SEd Tanous // Option currently returns no systems. TBD 32997f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 33007f3e84a1SEd Tanous systemName); 33017f3e84a1SEd Tanous return; 33027f3e84a1SEd Tanous } 330322d268cbSEd Tanous if (systemName != "system") 330422d268cbSEd Tanous { 330522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 330622d268cbSEd Tanous systemName); 330722d268cbSEd Tanous return; 330822d268cbSEd Tanous } 330922d268cbSEd Tanous 3310dd60b9edSEd Tanous asyncResp->res.addHeader( 3311dd60b9edSEd Tanous boost::beast::http::field::link, 3312dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3313dd60b9edSEd Tanous 33149f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3315cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 331698e386ecSGunnar Mills std::optional<std::string> assetTag; 3317c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 33183a2d0424SChris Cain std::optional<std::string> powerMode; 3319550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3320550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3321550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3322550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3323550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3324550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3325797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3326550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 33279dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3328550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3329550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3330550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3331550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3332550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3333550a6bf8SJiaqing Zhao 3334550a6bf8SJiaqing Zhao // clang-format off 333515ed6780SWilly Tu if (!json_util::readJsonPatch( 3336550a6bf8SJiaqing Zhao req, asyncResp->res, 3337550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 33387e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3339550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3340550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3341550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3342550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3343550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3344550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3345550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3346550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3347550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3348797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3349550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 33509dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3351550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3352550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3353550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3354550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3355550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 33566617338dSEd Tanous { 33576617338dSEd Tanous return; 33586617338dSEd Tanous } 3359550a6bf8SJiaqing Zhao // clang-format on 3360491d8ee7SSantosh Puranik 33618d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3362c45f0082SYong Li 336398e386ecSGunnar Mills if (assetTag) 336498e386ecSGunnar Mills { 336598e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 336698e386ecSGunnar Mills } 336798e386ecSGunnar Mills 3368550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3369c45f0082SYong Li { 3370f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3371c45f0082SYong Li } 3372c45f0082SYong Li 3373cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 337469f35306SGunnar Mills { 3375002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3376491d8ee7SSantosh Puranik } 3377550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 337869f35306SGunnar Mills { 3379550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 338069f35306SGunnar Mills } 3381ac7e1e0bSAli Ahmed 3382797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3383797d5daeSCorey Hardesty { 3384797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3385797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3386797d5daeSCorey Hardesty } 3387797d5daeSCorey Hardesty 3388550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3389ac7e1e0bSAli Ahmed { 3390c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 339169f35306SGunnar Mills } 3392265c1602SJohnathan Mantey 33939dcfe8c1SAlbert Zhang if (stopBootOnFault) 33949dcfe8c1SAlbert Zhang { 33959dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 33969dcfe8c1SAlbert Zhang } 33979dcfe8c1SAlbert Zhang 33989f8bfa7cSGunnar Mills if (locationIndicatorActive) 33999f8bfa7cSGunnar Mills { 340059a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 34019f8bfa7cSGunnar Mills } 34029f8bfa7cSGunnar Mills 34037e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 34047e860f15SJohn Edward Broadbent // passed 34059712f8acSEd Tanous if (indicatorLed) 34066617338dSEd Tanous { 3407f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3408002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3409d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3410d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 34116617338dSEd Tanous } 3412c6a620f2SGeorge Liu 3413c6a620f2SGeorge Liu if (powerRestorePolicy) 3414c6a620f2SGeorge Liu { 34154e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3416c6a620f2SGeorge Liu } 34173a2d0424SChris Cain 34183a2d0424SChris Cain if (powerMode) 34193a2d0424SChris Cain { 34203a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 34213a2d0424SChris Cain } 342237bbf98cSChris Cain 3423c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 342437bbf98cSChris Cain { 3425002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3426002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 342737bbf98cSChris Cain } 3428c1e219d5SEd Tanous } 34291cb1a9e6SAppaRao Puli 343038c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3431dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 34327f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3433c1e219d5SEd Tanous const std::string& /*systemName*/) 3434dd60b9edSEd Tanous { 3435dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3436dd60b9edSEd Tanous { 3437dd60b9edSEd Tanous return; 3438dd60b9edSEd Tanous } 3439dd60b9edSEd Tanous asyncResp->res.addHeader( 3440dd60b9edSEd Tanous boost::beast::http::field::link, 3441dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3442dd60b9edSEd Tanous } 344333e1f122SAndrew Geissler 344433e1f122SAndrew Geissler /** 344533e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 344633e1f122SAndrew Geissler * 344733e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 344833e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 344933e1f122SAndrew Geissler * 345033e1f122SAndrew Geissler * @return Emplaces correpsonding Redfish translated value(s) in 345133e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 345233e1f122SAndrew Geissler * allowableValues. 345333e1f122SAndrew Geissler */ 345433e1f122SAndrew Geissler inline void 345533e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran, 345633e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 345733e1f122SAndrew Geissler { 345833e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 345933e1f122SAndrew Geissler { 346033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 346133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 346233e1f122SAndrew Geissler } 346333e1f122SAndrew Geissler else if (dbusAllowedHostTran == 346433e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 346533e1f122SAndrew Geissler { 346633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 346733e1f122SAndrew Geissler } 346833e1f122SAndrew Geissler else if (dbusAllowedHostTran == 346933e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 347033e1f122SAndrew Geissler { 347133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 347233e1f122SAndrew Geissler } 347333e1f122SAndrew Geissler else if (dbusAllowedHostTran == 347433e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 347533e1f122SAndrew Geissler { 347633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 347733e1f122SAndrew Geissler } 347833e1f122SAndrew Geissler else 347933e1f122SAndrew Geissler { 348033e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 348133e1f122SAndrew Geissler } 348233e1f122SAndrew Geissler } 348333e1f122SAndrew Geissler 348433e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 348533e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 348633e1f122SAndrew Geissler const boost::system::error_code& ec, 348733e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 348833e1f122SAndrew Geissler { 348933e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 349033e1f122SAndrew Geissler 349133e1f122SAndrew Geissler // Supported on all systems currently 349233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 349333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 349433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 349533e1f122SAndrew Geissler 349633e1f122SAndrew Geissler if (ec) 349733e1f122SAndrew Geissler { 3498e715d14bSEd Tanous if ((ec.value() == 3499e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3500e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 350133e1f122SAndrew Geissler { 350233e1f122SAndrew Geissler // Property not implemented so just return defaults 350333e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 350433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 350533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 350633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 350733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 350833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 350933e1f122SAndrew Geissler } 351033e1f122SAndrew Geissler else 351133e1f122SAndrew Geissler { 351233e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 351333e1f122SAndrew Geissler messages::internalError(asyncResp->res); 351433e1f122SAndrew Geissler return; 351533e1f122SAndrew Geissler } 351633e1f122SAndrew Geissler } 351733e1f122SAndrew Geissler else 351833e1f122SAndrew Geissler { 351933e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 352033e1f122SAndrew Geissler { 352133e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 352233e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 352333e1f122SAndrew Geissler } 352433e1f122SAndrew Geissler } 352533e1f122SAndrew Geissler 352633e1f122SAndrew Geissler nlohmann::json::object_t parameter; 352733e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 352833e1f122SAndrew Geissler parameter["Required"] = true; 352933e1f122SAndrew Geissler parameter["DataType"] = "String"; 353033e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 353133e1f122SAndrew Geissler nlohmann::json::array_t parameters; 353233e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 353333e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 353433e1f122SAndrew Geissler } 353533e1f122SAndrew Geissler 3536c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3537c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 353822d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3539c1e219d5SEd Tanous const std::string& systemName) 3540c1e219d5SEd Tanous { 35413ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 354245ca1b86SEd Tanous { 354345ca1b86SEd Tanous return; 354445ca1b86SEd Tanous } 35457f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 35467f3e84a1SEd Tanous { 35477f3e84a1SEd Tanous // Option currently returns no systems. TBD 35487f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 35497f3e84a1SEd Tanous systemName); 35507f3e84a1SEd Tanous return; 35517f3e84a1SEd Tanous } 3552746b56f3SAsmitha Karunanithi 3553746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3554746b56f3SAsmitha Karunanithi { 3555746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3556746b56f3SAsmitha Karunanithi return; 3557746b56f3SAsmitha Karunanithi } 3558746b56f3SAsmitha Karunanithi 355922d268cbSEd Tanous if (systemName != "system") 356022d268cbSEd Tanous { 356122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 356222d268cbSEd Tanous systemName); 356322d268cbSEd Tanous return; 356422d268cbSEd Tanous } 356522d268cbSEd Tanous 3566dd60b9edSEd Tanous asyncResp->res.addHeader( 3567dd60b9edSEd Tanous boost::beast::http::field::link, 3568dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 35691476687dSEd Tanous 35701476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 35711476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3572c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 35731476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 35741476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 35753215e700SNan Zhou 357633e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 357733e1f122SAndrew Geissler sdbusplus::asio::getProperty<std::vector<std::string>>( 357833e1f122SAndrew Geissler *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 357933e1f122SAndrew Geissler "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 358033e1f122SAndrew Geissler "AllowedHostTransitions", 358133e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 358233e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 358333e1f122SAndrew Geissler afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions); 358433e1f122SAndrew Geissler }); 3585c1e219d5SEd Tanous } 3586c1e219d5SEd Tanous /** 3587c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3588c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3589c1e219d5SEd Tanous */ 3590100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3591c1e219d5SEd Tanous { 3592100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3593100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3594100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3595100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3596100afe56SEd Tanous 3597100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3598100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3599100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3600100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3601100afe56SEd Tanous 3602100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3603100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3604100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3605100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3606100afe56SEd Tanous 3607100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3608100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3609100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3610100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3611100afe56SEd Tanous 3612100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3613100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3614100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3615100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3616100afe56SEd Tanous 3617100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3618100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3619100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3620100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3621100afe56SEd Tanous 3622c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3623c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3624c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3625c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3626c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3627c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3628c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3629c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 36301cb1a9e6SAppaRao Puli } 3631c5b2abe0SLewanczyk, Dawid } // namespace redfish 3632