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" 25746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 261c8fba97SJames Feist #include "led.hpp" 27f4c99e70SEd Tanous #include "query.hpp" 28c5d03ff4SJennifer Lee #include "redfish_util.hpp" 293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 313ccb3adbSEd Tanous #include "utils/json_utils.hpp" 32472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 333ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 342b82937eSEd Tanous #include "utils/time_utils.hpp" 35c5d03ff4SJennifer Lee 36fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 379712f8acSEd Tanous #include <boost/container/flat_map.hpp> 38e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 3933e1f122SAndrew Geissler #include <boost/system/linux_error.hpp> 40ef4c65b7SEd Tanous #include <boost/url/format.hpp> 411e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 42fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 43bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 441214b7e7SGunnar Mills 457a1dbc48SGeorge Liu #include <array> 4633e1f122SAndrew Geissler #include <memory> 476b9ac4f2SChris Cain #include <string> 487a1dbc48SGeorge Liu #include <string_view> 49abf2add6SEd Tanous #include <variant> 506b9ac4f2SChris Cain #include <vector> 51c5b2abe0SLewanczyk, Dawid 521abe55efSEd Tanous namespace redfish 531abe55efSEd Tanous { 54c5b2abe0SLewanczyk, Dawid 555c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 565c3e9272SAbhishek Patel protocolToDBusForSystems{ 575c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 585c3e9272SAbhishek Patel 599d3ae10eSAlpana Kumari /** 609d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 619d3ae10eSAlpana Kumari * 62ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 639d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 649d3ae10eSAlpana Kumari * 659d3ae10eSAlpana Kumari * @return None. 669d3ae10eSAlpana Kumari */ 678d1b46d7Szhanghch05 inline void 68ac106bf6SEd Tanous updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 691e1e598dSJonathan Doman bool isDimmFunctional) 709d3ae10eSAlpana Kumari { 7162598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 729d3ae10eSAlpana Kumari 739d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 749d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 759d3ae10eSAlpana Kumari // ENABLED. 7602cad96eSEd Tanous const nlohmann::json& prevMemSummary = 77ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 789d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 799d3ae10eSAlpana Kumari { 80e05aec50SEd Tanous if (isDimmFunctional) 819d3ae10eSAlpana Kumari { 82ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 839d3ae10eSAlpana Kumari "Enabled"; 849d3ae10eSAlpana Kumari } 859d3ae10eSAlpana Kumari } 869d3ae10eSAlpana Kumari } 879d3ae10eSAlpana Kumari 8857e8c9beSAlpana Kumari /* 8957e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 9057e8c9beSAlpana Kumari * CPU Functional State 9157e8c9beSAlpana Kumari * 92ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 9357e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9457e8c9beSAlpana Kumari * 9557e8c9beSAlpana Kumari * @return None. 9657e8c9beSAlpana Kumari */ 97ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 98ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 9957e8c9beSAlpana Kumari { 10062598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 10157e8c9beSAlpana Kumari 10202cad96eSEd Tanous const nlohmann::json& prevProcState = 103ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10457e8c9beSAlpana Kumari 10557e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10657e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10757e8c9beSAlpana Kumari // Functional. 10857e8c9beSAlpana Kumari if (prevProcState == "Disabled") 10957e8c9beSAlpana Kumari { 110e05aec50SEd Tanous if (isCpuFunctional) 11157e8c9beSAlpana Kumari { 112ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 11357e8c9beSAlpana Kumari "Enabled"; 11457e8c9beSAlpana Kumari } 11557e8c9beSAlpana Kumari } 11657e8c9beSAlpana Kumari } 11757e8c9beSAlpana Kumari 118cf0e004cSNinad Palsule /* 119cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 120cf0e004cSNinad Palsule * 121ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 122cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 123cf0e004cSNinad Palsule * 124cf0e004cSNinad Palsule * @return None. 125cf0e004cSNinad Palsule */ 126cf0e004cSNinad Palsule inline void 127ac106bf6SEd Tanous modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 128cf0e004cSNinad Palsule bool isCpuPresent) 129cf0e004cSNinad Palsule { 13062598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 131cf0e004cSNinad Palsule 132cf0e004cSNinad Palsule if (isCpuPresent) 133cf0e004cSNinad Palsule { 134cf0e004cSNinad Palsule nlohmann::json& procCount = 135ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 136cf0e004cSNinad Palsule auto* procCountPtr = 137cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 138cf0e004cSNinad Palsule if (procCountPtr != nullptr) 139cf0e004cSNinad Palsule { 140cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 141cf0e004cSNinad Palsule *procCountPtr += 1; 142cf0e004cSNinad Palsule } 143cf0e004cSNinad Palsule } 144cf0e004cSNinad Palsule } 145cf0e004cSNinad Palsule 146382d6475SAli Ahmed inline void getProcessorProperties( 147ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 148382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 149382d6475SAli Ahmed properties) 15003fbed92SAli Ahmed { 15162598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 15203fbed92SAli Ahmed 15303fbed92SAli Ahmed // TODO: Get Model 15403fbed92SAli Ahmed 155bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15603fbed92SAli Ahmed 157bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 158bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 15903fbed92SAli Ahmed 160bc1d29deSKrzysztof Grobelny if (!success) 16103fbed92SAli Ahmed { 162ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16303fbed92SAli Ahmed return; 16403fbed92SAli Ahmed } 16503fbed92SAli Ahmed 166bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16703fbed92SAli Ahmed { 168bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 169ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 170bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 171bc1d29deSKrzysztof Grobelny 172bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 173bc1d29deSKrzysztof Grobelny { 174bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17503fbed92SAli Ahmed } 17603fbed92SAli Ahmed else 17703fbed92SAli Ahmed { 178bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 17903fbed92SAli Ahmed } 18003fbed92SAli Ahmed } 18103fbed92SAli Ahmed } 18203fbed92SAli Ahmed 18303fbed92SAli Ahmed /* 18403fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18503fbed92SAli Ahmed * 186ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 18703fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 18803fbed92SAli Ahmed * @param[in] path dbus path for Cpu 18903fbed92SAli Ahmed * 19003fbed92SAli Ahmed * @return None. 19103fbed92SAli Ahmed */ 192ac106bf6SEd Tanous inline void 193ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 194ac106bf6SEd Tanous const std::string& service, const std::string& path) 19503fbed92SAli Ahmed { 196ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 197382d6475SAli Ahmed const bool cpuPresenceCheck) { 198382d6475SAli Ahmed if (ec3) 199382d6475SAli Ahmed { 20062598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 201382d6475SAli Ahmed return; 202382d6475SAli Ahmed } 203ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 204382d6475SAli Ahmed }; 205382d6475SAli Ahmed 206cf0e004cSNinad Palsule // Get the Presence of CPU 207cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 208cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 209cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 210cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 211cf0e004cSNinad Palsule 212bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 213bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 214bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 215ac106bf6SEd Tanous [asyncResp, service, 2165e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 217b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 21803fbed92SAli Ahmed if (ec2) 21903fbed92SAli Ahmed { 22062598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 221ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22203fbed92SAli Ahmed return; 22303fbed92SAli Ahmed } 224ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 225bc1d29deSKrzysztof Grobelny }); 22603fbed92SAli Ahmed } 22703fbed92SAli Ahmed 22857e8c9beSAlpana Kumari /* 229cf0e004cSNinad Palsule * @brief processMemoryProperties fields 230cf0e004cSNinad Palsule * 231ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 232cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 233cf0e004cSNinad Palsule * 234cf0e004cSNinad Palsule * @return None. 235cf0e004cSNinad Palsule */ 236cf0e004cSNinad Palsule inline void 237ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 238cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 239cf0e004cSNinad Palsule { 24062598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 241cf0e004cSNinad Palsule 242cf0e004cSNinad Palsule if (properties.empty()) 243cf0e004cSNinad Palsule { 244cf0e004cSNinad Palsule return; 245cf0e004cSNinad Palsule } 246cf0e004cSNinad Palsule 247cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 248cf0e004cSNinad Palsule 249cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 250cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 251cf0e004cSNinad Palsule memorySizeInKB); 252cf0e004cSNinad Palsule 253cf0e004cSNinad Palsule if (!success) 254cf0e004cSNinad Palsule { 255ac106bf6SEd Tanous messages::internalError(asyncResp->res); 256cf0e004cSNinad Palsule return; 257cf0e004cSNinad Palsule } 258cf0e004cSNinad Palsule 259cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 260cf0e004cSNinad Palsule { 261cf0e004cSNinad Palsule nlohmann::json& totalMemory = 262ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 263dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 264cf0e004cSNinad Palsule if (preValue == nullptr) 265cf0e004cSNinad Palsule { 266ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 267dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 268cf0e004cSNinad Palsule } 269cf0e004cSNinad Palsule else 270cf0e004cSNinad Palsule { 271ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 272dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 273dfb2b408SPriyanga Ramasamy *preValue; 274cf0e004cSNinad Palsule } 275cf0e004cSNinad Palsule } 276cf0e004cSNinad Palsule } 277cf0e004cSNinad Palsule 278cf0e004cSNinad Palsule /* 279cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 280cf0e004cSNinad Palsule * 281ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 282cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 283cf0e004cSNinad Palsule * @param[in] path dbus path for memory 284cf0e004cSNinad Palsule * 285cf0e004cSNinad Palsule * @return None. 286cf0e004cSNinad Palsule */ 287ac106bf6SEd Tanous inline void 288ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 289ac106bf6SEd Tanous const std::string& service, const std::string& path) 290cf0e004cSNinad Palsule { 291cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 292cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 293cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 294ac106bf6SEd Tanous [asyncResp, service, 295cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 296cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 297cf0e004cSNinad Palsule if (ec2) 298cf0e004cSNinad Palsule { 29962598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 300ac106bf6SEd Tanous messages::internalError(asyncResp->res); 301cf0e004cSNinad Palsule return; 302cf0e004cSNinad Palsule } 30351bd2d8aSGunnar Mills processMemoryProperties(asyncResp, properties); 304cf0e004cSNinad Palsule }); 305cf0e004cSNinad Palsule } 306cf0e004cSNinad Palsule 307a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 308a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 309a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& properties) 3101abe55efSEd Tanous { 311a974c132SLakshmi Yadlapati if (ec) 312a974c132SLakshmi Yadlapati { 313a974c132SLakshmi Yadlapati BMCWEB_LOG_ERROR("DBUS response error {}", ec); 314a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 315a974c132SLakshmi Yadlapati return; 316a974c132SLakshmi Yadlapati } 317a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size()); 318a974c132SLakshmi Yadlapati 319a974c132SLakshmi Yadlapati const std::string* uUID = nullptr; 320a974c132SLakshmi Yadlapati 321a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 322a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID); 323a974c132SLakshmi Yadlapati 324a974c132SLakshmi Yadlapati if (!success) 325a974c132SLakshmi Yadlapati { 326a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 327a974c132SLakshmi Yadlapati return; 328a974c132SLakshmi Yadlapati } 329a974c132SLakshmi Yadlapati 330a974c132SLakshmi Yadlapati if (uUID != nullptr) 331a974c132SLakshmi Yadlapati { 332a974c132SLakshmi Yadlapati std::string valueStr = *uUID; 333a974c132SLakshmi Yadlapati if (valueStr.size() == 32) 334a974c132SLakshmi Yadlapati { 335a974c132SLakshmi Yadlapati valueStr.insert(8, 1, '-'); 336a974c132SLakshmi Yadlapati valueStr.insert(13, 1, '-'); 337a974c132SLakshmi Yadlapati valueStr.insert(18, 1, '-'); 338a974c132SLakshmi Yadlapati valueStr.insert(23, 1, '-'); 339a974c132SLakshmi Yadlapati } 340a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("UUID = {}", valueStr); 341a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["UUID"] = valueStr; 342a974c132SLakshmi Yadlapati } 343a974c132SLakshmi Yadlapati } 344a974c132SLakshmi Yadlapati 345a974c132SLakshmi Yadlapati inline void 346a974c132SLakshmi Yadlapati afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 347a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 348a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& propertiesList) 349a974c132SLakshmi Yadlapati { 350a974c132SLakshmi Yadlapati if (ec) 351a974c132SLakshmi Yadlapati { 352a974c132SLakshmi Yadlapati // doesn't have to include this 353a974c132SLakshmi Yadlapati // interface 354a974c132SLakshmi Yadlapati return; 355a974c132SLakshmi Yadlapati } 356a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size()); 357a974c132SLakshmi Yadlapati 358a974c132SLakshmi Yadlapati const std::string* partNumber = nullptr; 359a974c132SLakshmi Yadlapati const std::string* serialNumber = nullptr; 360a974c132SLakshmi Yadlapati const std::string* manufacturer = nullptr; 361a974c132SLakshmi Yadlapati const std::string* model = nullptr; 362a974c132SLakshmi Yadlapati const std::string* subModel = nullptr; 363a974c132SLakshmi Yadlapati 364a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 365a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber", 366a974c132SLakshmi Yadlapati partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 367a974c132SLakshmi Yadlapati "Model", model, "SubModel", subModel); 368a974c132SLakshmi Yadlapati 369a974c132SLakshmi Yadlapati if (!success) 370a974c132SLakshmi Yadlapati { 371a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 372a974c132SLakshmi Yadlapati return; 373a974c132SLakshmi Yadlapati } 374a974c132SLakshmi Yadlapati 375a974c132SLakshmi Yadlapati if (partNumber != nullptr) 376a974c132SLakshmi Yadlapati { 377a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["PartNumber"] = *partNumber; 378a974c132SLakshmi Yadlapati } 379a974c132SLakshmi Yadlapati 380a974c132SLakshmi Yadlapati if (serialNumber != nullptr) 381a974c132SLakshmi Yadlapati { 382a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 383a974c132SLakshmi Yadlapati } 384a974c132SLakshmi Yadlapati 385a974c132SLakshmi Yadlapati if (manufacturer != nullptr) 386a974c132SLakshmi Yadlapati { 387a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 388a974c132SLakshmi Yadlapati } 389a974c132SLakshmi Yadlapati 390a974c132SLakshmi Yadlapati if (model != nullptr) 391a974c132SLakshmi Yadlapati { 392a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Model"] = *model; 393a974c132SLakshmi Yadlapati } 394a974c132SLakshmi Yadlapati 395a974c132SLakshmi Yadlapati if (subModel != nullptr) 396a974c132SLakshmi Yadlapati { 397a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SubModel"] = *subModel; 398a974c132SLakshmi Yadlapati } 399a974c132SLakshmi Yadlapati 400a974c132SLakshmi Yadlapati // Grab the bios version 401a974c132SLakshmi Yadlapati sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, 402a974c132SLakshmi Yadlapati "BiosVersion", false); 403a974c132SLakshmi Yadlapati } 404a974c132SLakshmi Yadlapati 405a974c132SLakshmi Yadlapati inline void 406a974c132SLakshmi Yadlapati afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 407a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 408a974c132SLakshmi Yadlapati const std::string& value) 409a974c132SLakshmi Yadlapati { 410a974c132SLakshmi Yadlapati if (ec) 411a974c132SLakshmi Yadlapati { 412a974c132SLakshmi Yadlapati // doesn't have to include this 413a974c132SLakshmi Yadlapati // interface 414a974c132SLakshmi Yadlapati return; 415a974c132SLakshmi Yadlapati } 416a974c132SLakshmi Yadlapati 417a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["AssetTag"] = value; 418a974c132SLakshmi Yadlapati } 419a974c132SLakshmi Yadlapati 420a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree( 421a974c132SLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 422a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 423a974c132SLakshmi Yadlapati const dbus::utility::MapperGetSubTreeResponse& subtree) 424a974c132SLakshmi Yadlapati { 4251abe55efSEd Tanous if (ec) 4261abe55efSEd Tanous { 427b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 428ac106bf6SEd Tanous messages::internalError(asyncResp->res); 429c5b2abe0SLewanczyk, Dawid return; 430c5b2abe0SLewanczyk, Dawid } 431c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 432002d39b4SEd Tanous for (const std::pair< 433002d39b4SEd Tanous std::string, 434002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 4351214b7e7SGunnar Mills object : subtree) 4361abe55efSEd Tanous { 437c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 43862598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 439002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 4401214b7e7SGunnar Mills connectionNames = object.second; 44126f6976fSEd Tanous if (connectionNames.empty()) 4421abe55efSEd Tanous { 443c5b2abe0SLewanczyk, Dawid continue; 444c5b2abe0SLewanczyk, Dawid } 445029573d4SEd Tanous 4466c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4476c34de48SEd Tanous // BiosVer 44804a258f4SEd Tanous for (const auto& connection : connectionNames) 4491abe55efSEd Tanous { 45004a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4511abe55efSEd Tanous { 452a974c132SLakshmi Yadlapati if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") 4531abe55efSEd Tanous { 45462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 4559d3ae10eSAlpana Kumari 456ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4575fd0aafbSNinad Palsule } 45804a258f4SEd Tanous else if (interfaceName == 45904a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4601abe55efSEd Tanous { 46162598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 46257e8c9beSAlpana Kumari 463ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4645fd0aafbSNinad Palsule } 465002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4661abe55efSEd Tanous { 46762598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 468bc1d29deSKrzysztof Grobelny 469bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 470a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 471a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 472ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 473b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4741214b7e7SGunnar Mills properties) { 475a974c132SLakshmi Yadlapati afterGetUUID(asyncResp, ec3, properties); 476bc1d29deSKrzysztof Grobelny }); 477c5b2abe0SLewanczyk, Dawid } 478029573d4SEd Tanous else if (interfaceName == 479029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4801abe55efSEd Tanous { 481bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 482a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 483bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 484a974c132SLakshmi Yadlapati [asyncResp](const boost::system::error_code& ec3, 485b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 486a974c132SLakshmi Yadlapati properties) { 487a974c132SLakshmi Yadlapati afterGetInventory(asyncResp, ec3, properties); 488bc1d29deSKrzysztof Grobelny }); 489e4a4b9a9SJames Feist 4901e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 491a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 4921e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 4931e1e598dSJonathan Doman "AssetTag", 4941e1e598dSJonathan Doman "AssetTag", 495a974c132SLakshmi Yadlapati std::bind_front(afterGetAssetTag, asyncResp)); 496a974c132SLakshmi Yadlapati } 497a974c132SLakshmi Yadlapati } 498a974c132SLakshmi Yadlapati } 499a974c132SLakshmi Yadlapati } 500a974c132SLakshmi Yadlapati } 501a974c132SLakshmi Yadlapati 502a974c132SLakshmi Yadlapati /* 503a974c132SLakshmi Yadlapati * @brief Retrieves computer system properties over dbus 504a974c132SLakshmi Yadlapati * 505a974c132SLakshmi Yadlapati * @param[in] asyncResp Shared pointer for completing asynchronous calls 506a974c132SLakshmi Yadlapati * 507a974c132SLakshmi Yadlapati * @return None. 508a974c132SLakshmi Yadlapati */ 509a974c132SLakshmi Yadlapati inline void 51051bd2d8aSGunnar Mills getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 511e4a4b9a9SJames Feist { 512a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get available system components."); 513a974c132SLakshmi Yadlapati constexpr std::array<std::string_view, 5> interfaces = { 514a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 515a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Cpu", 516a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Dimm", 517a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.System", 518a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 519a974c132SLakshmi Yadlapati }; 520a974c132SLakshmi Yadlapati dbus::utility::getSubTree( 521a974c132SLakshmi Yadlapati "/xyz/openbmc_project/inventory", 0, interfaces, 52251bd2d8aSGunnar Mills std::bind_front(afterSystemGetSubTree, asyncResp)); 523c5b2abe0SLewanczyk, Dawid } 524c5b2abe0SLewanczyk, Dawid 525c5b2abe0SLewanczyk, Dawid /** 526c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 527c5b2abe0SLewanczyk, Dawid * 528ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 529c5b2abe0SLewanczyk, Dawid * 530c5b2abe0SLewanczyk, Dawid * @return None. 531c5b2abe0SLewanczyk, Dawid */ 532ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5331abe55efSEd Tanous { 53462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 5351e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5361e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 5371e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 5381e1e598dSJonathan Doman "CurrentHostState", 539ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 5401e1e598dSJonathan Doman const std::string& hostState) { 5411abe55efSEd Tanous if (ec) 5421abe55efSEd Tanous { 54322228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 54422228c28SAndrew Geissler { 54522228c28SAndrew Geissler // Service not available, no error, just don't return 54622228c28SAndrew Geissler // host state info 54762598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 54822228c28SAndrew Geissler return; 54922228c28SAndrew Geissler } 55062598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 551ac106bf6SEd Tanous messages::internalError(asyncResp->res); 552c5b2abe0SLewanczyk, Dawid return; 553c5b2abe0SLewanczyk, Dawid } 5546617338dSEd Tanous 55562598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 556c5b2abe0SLewanczyk, Dawid // Verify Host State 5571e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5581abe55efSEd Tanous { 559ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 560ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 5611abe55efSEd Tanous } 5621e1e598dSJonathan Doman else if (hostState == 5630fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5648c888608SGunnar Mills { 565ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 566ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 5678c888608SGunnar Mills } 5681e1e598dSJonathan Doman else if (hostState == 5690fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 57083935af9SAndrew Geissler { 571ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 572ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 57383935af9SAndrew Geissler } 5740fda0f12SGeorge Liu else if ( 5751e1e598dSJonathan Doman hostState == 5760fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5771a2a1437SAndrew Geissler { 578ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 579ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 5801a2a1437SAndrew Geissler } 581002d39b4SEd Tanous else if (hostState == 5820fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5831a2a1437SAndrew Geissler { 584ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 585ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 5861a2a1437SAndrew Geissler } 5871abe55efSEd Tanous else 5881abe55efSEd Tanous { 589ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 590ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 591c5b2abe0SLewanczyk, Dawid } 5921e1e598dSJonathan Doman }); 593c5b2abe0SLewanczyk, Dawid } 594c5b2abe0SLewanczyk, Dawid 595c5b2abe0SLewanczyk, Dawid /** 596786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 597491d8ee7SSantosh Puranik * 598491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 599491d8ee7SSantosh Puranik * 600491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 601491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 602491d8ee7SSantosh Puranik */ 60323a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 604491d8ee7SSantosh Puranik { 605491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 606491d8ee7SSantosh Puranik { 607491d8ee7SSantosh Puranik return "None"; 608491d8ee7SSantosh Puranik } 6093174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 610491d8ee7SSantosh Puranik { 611491d8ee7SSantosh Puranik return "Hdd"; 612491d8ee7SSantosh Puranik } 6133174e4dfSEd Tanous if (dbusSource == 614a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 615491d8ee7SSantosh Puranik { 616491d8ee7SSantosh Puranik return "Cd"; 617491d8ee7SSantosh Puranik } 6183174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 619491d8ee7SSantosh Puranik { 620491d8ee7SSantosh Puranik return "Pxe"; 621491d8ee7SSantosh Puranik } 6223174e4dfSEd Tanous if (dbusSource == 623944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6249f16b2c1SJennifer Lee { 6259f16b2c1SJennifer Lee return "Usb"; 6269f16b2c1SJennifer Lee } 627491d8ee7SSantosh Puranik return ""; 628491d8ee7SSantosh Puranik } 629491d8ee7SSantosh Puranik 630491d8ee7SSantosh Puranik /** 631cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 632cd9a4666SKonstantin Aladyshev * 633cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 634cd9a4666SKonstantin Aladyshev * 635cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 636cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 637cd9a4666SKonstantin Aladyshev */ 638cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 639cd9a4666SKonstantin Aladyshev { 640cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 641cd9a4666SKonstantin Aladyshev { 642cd9a4666SKonstantin Aladyshev return "Legacy"; 643cd9a4666SKonstantin Aladyshev } 644cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 645cd9a4666SKonstantin Aladyshev { 646cd9a4666SKonstantin Aladyshev return "UEFI"; 647cd9a4666SKonstantin Aladyshev } 648cd9a4666SKonstantin Aladyshev return ""; 649cd9a4666SKonstantin Aladyshev } 650cd9a4666SKonstantin Aladyshev 651cd9a4666SKonstantin Aladyshev /** 652786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 653491d8ee7SSantosh Puranik * 654491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 655491d8ee7SSantosh Puranik * 656491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 657491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 658491d8ee7SSantosh Puranik */ 65923a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 660491d8ee7SSantosh Puranik { 661491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 662491d8ee7SSantosh Puranik { 663491d8ee7SSantosh Puranik return "None"; 664491d8ee7SSantosh Puranik } 6653174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 666491d8ee7SSantosh Puranik { 667491d8ee7SSantosh Puranik return "Diags"; 668491d8ee7SSantosh Puranik } 6693174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 670491d8ee7SSantosh Puranik { 671491d8ee7SSantosh Puranik return "BiosSetup"; 672491d8ee7SSantosh Puranik } 673491d8ee7SSantosh Puranik return ""; 674491d8ee7SSantosh Puranik } 675491d8ee7SSantosh Puranik 676491d8ee7SSantosh Puranik /** 677e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 678e43914b3SAndrew Geissler * 679e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 680e43914b3SAndrew Geissler * 681e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 682e43914b3SAndrew Geissler * translation cannot be done, returns "None". 683e43914b3SAndrew Geissler */ 684e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 685e43914b3SAndrew Geissler { 686e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 687e43914b3SAndrew Geissler // enum 688e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 689e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 690e43914b3SAndrew Geissler "ProgressStages.Unspecified") 691e43914b3SAndrew Geissler { 692e43914b3SAndrew Geissler rfBpLastState = "None"; 693e43914b3SAndrew Geissler } 694e43914b3SAndrew Geissler else if (dbusBootProgress == 695e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 696e43914b3SAndrew Geissler "PrimaryProcInit") 697e43914b3SAndrew Geissler { 698e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 699e43914b3SAndrew Geissler } 700e43914b3SAndrew Geissler else if (dbusBootProgress == 701e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 702e43914b3SAndrew Geissler "BusInit") 703e43914b3SAndrew Geissler { 704e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 705e43914b3SAndrew Geissler } 706e43914b3SAndrew Geissler else if (dbusBootProgress == 707e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 708e43914b3SAndrew Geissler "MemoryInit") 709e43914b3SAndrew Geissler { 710e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 711e43914b3SAndrew Geissler } 712e43914b3SAndrew Geissler else if (dbusBootProgress == 713e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 714e43914b3SAndrew Geissler "SecondaryProcInit") 715e43914b3SAndrew Geissler { 716e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 717e43914b3SAndrew Geissler } 718e43914b3SAndrew Geissler else if (dbusBootProgress == 719e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 720e43914b3SAndrew Geissler "PCIInit") 721e43914b3SAndrew Geissler { 722e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 723e43914b3SAndrew Geissler } 724e43914b3SAndrew Geissler else if (dbusBootProgress == 725e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 726e43914b3SAndrew Geissler "SystemSetup") 727e43914b3SAndrew Geissler { 728e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 729e43914b3SAndrew Geissler } 730e43914b3SAndrew Geissler else if (dbusBootProgress == 731e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 732e43914b3SAndrew Geissler "SystemInitComplete") 733e43914b3SAndrew Geissler { 734e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 735e43914b3SAndrew Geissler } 736e43914b3SAndrew Geissler else if (dbusBootProgress == 737e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 738e43914b3SAndrew Geissler "OSStart") 739e43914b3SAndrew Geissler { 740e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 741e43914b3SAndrew Geissler } 742e43914b3SAndrew Geissler else if (dbusBootProgress == 743e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 744e43914b3SAndrew Geissler "OSRunning") 745e43914b3SAndrew Geissler { 746e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 747e43914b3SAndrew Geissler } 748e43914b3SAndrew Geissler else 749e43914b3SAndrew Geissler { 75062598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 751e43914b3SAndrew Geissler // Just return the default 752e43914b3SAndrew Geissler } 753e43914b3SAndrew Geissler return rfBpLastState; 754e43914b3SAndrew Geissler } 755e43914b3SAndrew Geissler 756e43914b3SAndrew Geissler /** 757786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 758491d8ee7SSantosh Puranik * 759491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 760944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 761944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 762491d8ee7SSantosh Puranik * 763944ffaf9SJohnathan Mantey * @return Integer error code. 764491d8ee7SSantosh Puranik */ 765ac106bf6SEd Tanous inline int 766ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 767ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 768ac106bf6SEd Tanous std::string& bootMode) 769491d8ee7SSantosh Puranik { 770c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 771c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 772944ffaf9SJohnathan Mantey 773491d8ee7SSantosh Puranik if (rfSource == "None") 774491d8ee7SSantosh Puranik { 775944ffaf9SJohnathan Mantey return 0; 776491d8ee7SSantosh Puranik } 7773174e4dfSEd Tanous if (rfSource == "Pxe") 778491d8ee7SSantosh Puranik { 779944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 780944ffaf9SJohnathan Mantey } 781944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 782944ffaf9SJohnathan Mantey { 783944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 784944ffaf9SJohnathan Mantey } 785944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 786944ffaf9SJohnathan Mantey { 787944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 788944ffaf9SJohnathan Mantey } 789944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 790944ffaf9SJohnathan Mantey { 791944ffaf9SJohnathan Mantey bootSource = 792944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 793944ffaf9SJohnathan Mantey } 794944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 795944ffaf9SJohnathan Mantey { 796944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 797491d8ee7SSantosh Puranik } 7989f16b2c1SJennifer Lee else if (rfSource == "Usb") 7999f16b2c1SJennifer Lee { 800944ffaf9SJohnathan Mantey bootSource = 801944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8029f16b2c1SJennifer Lee } 803491d8ee7SSantosh Puranik else 804491d8ee7SSantosh Puranik { 80562598e31SEd Tanous BMCWEB_LOG_DEBUG( 80662598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 80762598e31SEd Tanous bootSource); 808ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 809944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 810944ffaf9SJohnathan Mantey return -1; 811491d8ee7SSantosh Puranik } 812944ffaf9SJohnathan Mantey return 0; 813491d8ee7SSantosh Puranik } 8141981771bSAli Ahmed 815978b8803SAndrew Geissler /** 816978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 817978b8803SAndrew Geissler * 818ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 819978b8803SAndrew Geissler * 820978b8803SAndrew Geissler * @return None. 821978b8803SAndrew Geissler */ 822ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 823978b8803SAndrew Geissler { 8241e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8251e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8261e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8271e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 828ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8291e1e598dSJonathan Doman const std::string& bootProgressStr) { 830978b8803SAndrew Geissler if (ec) 831978b8803SAndrew Geissler { 832978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 833978b8803SAndrew Geissler // not found 834978b8803SAndrew Geissler return; 835978b8803SAndrew Geissler } 836978b8803SAndrew Geissler 83762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 838978b8803SAndrew Geissler 839ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 840e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8411e1e598dSJonathan Doman }); 842978b8803SAndrew Geissler } 843491d8ee7SSantosh Puranik 844491d8ee7SSantosh Puranik /** 845b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 846b6d5d45cSHieu Huynh * 847ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 848b6d5d45cSHieu Huynh * 849b6d5d45cSHieu Huynh * @return None. 850b6d5d45cSHieu Huynh */ 851b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 852ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 853b6d5d45cSHieu Huynh { 854b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 855b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 856b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 857b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 858ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 859b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 860b6d5d45cSHieu Huynh if (ec) 861b6d5d45cSHieu Huynh { 86262598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 863b6d5d45cSHieu Huynh return; 864b6d5d45cSHieu Huynh } 865b6d5d45cSHieu Huynh 866b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 867b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 868b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 869b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 870b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 871b6d5d45cSHieu Huynh 872b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 873ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 874b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 875b6d5d45cSHieu Huynh }); 876b6d5d45cSHieu Huynh } 877b6d5d45cSHieu Huynh 878b6d5d45cSHieu Huynh /** 879c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 880cd9a4666SKonstantin Aladyshev * 881ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 882cd9a4666SKonstantin Aladyshev * 883cd9a4666SKonstantin Aladyshev * @return None. 884cd9a4666SKonstantin Aladyshev */ 885cd9a4666SKonstantin Aladyshev 886ac106bf6SEd Tanous inline void 887ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 888cd9a4666SKonstantin Aladyshev { 8891e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8901e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 8911e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 8921e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 893ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8941e1e598dSJonathan Doman const std::string& bootType) { 895cd9a4666SKonstantin Aladyshev if (ec) 896cd9a4666SKonstantin Aladyshev { 897cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 898cd9a4666SKonstantin Aladyshev return; 899cd9a4666SKonstantin Aladyshev } 900cd9a4666SKonstantin Aladyshev 90162598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 902cd9a4666SKonstantin Aladyshev 903ac106bf6SEd Tanous asyncResp->res 904ac106bf6SEd Tanous .jsonValue["Boot"] 905002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 906613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 907cd9a4666SKonstantin Aladyshev 9081e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 909cd9a4666SKonstantin Aladyshev if (rfType.empty()) 910cd9a4666SKonstantin Aladyshev { 911ac106bf6SEd Tanous messages::internalError(asyncResp->res); 912cd9a4666SKonstantin Aladyshev return; 913cd9a4666SKonstantin Aladyshev } 914cd9a4666SKonstantin Aladyshev 915ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9161e1e598dSJonathan Doman }); 917cd9a4666SKonstantin Aladyshev } 918cd9a4666SKonstantin Aladyshev 919cd9a4666SKonstantin Aladyshev /** 920c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 921491d8ee7SSantosh Puranik * 922ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 923491d8ee7SSantosh Puranik * 924491d8ee7SSantosh Puranik * @return None. 925491d8ee7SSantosh Puranik */ 926c21865c4SKonstantin Aladyshev 927ac106bf6SEd Tanous inline void 928ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 929491d8ee7SSantosh Puranik { 9301e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9311e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9321e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9331e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 934ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9351e1e598dSJonathan Doman const std::string& bootModeStr) { 936491d8ee7SSantosh Puranik if (ec) 937491d8ee7SSantosh Puranik { 938b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 939ac106bf6SEd Tanous messages::internalError(asyncResp->res); 940491d8ee7SSantosh Puranik return; 941491d8ee7SSantosh Puranik } 942491d8ee7SSantosh Puranik 94362598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 944491d8ee7SSantosh Puranik 945ac106bf6SEd Tanous asyncResp->res 9460fda0f12SGeorge Liu .jsonValue["Boot"] 947002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 948002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 949491d8ee7SSantosh Puranik 9501e1e598dSJonathan Doman if (bootModeStr != 951491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 952491d8ee7SSantosh Puranik { 9531e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 954491d8ee7SSantosh Puranik if (!rfMode.empty()) 955491d8ee7SSantosh Puranik { 956ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 957491d8ee7SSantosh Puranik rfMode; 958491d8ee7SSantosh Puranik } 959491d8ee7SSantosh Puranik } 9601e1e598dSJonathan Doman }); 961491d8ee7SSantosh Puranik } 962491d8ee7SSantosh Puranik 963491d8ee7SSantosh Puranik /** 964c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 965491d8ee7SSantosh Puranik * 966ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 967491d8ee7SSantosh Puranik * 968491d8ee7SSantosh Puranik * @return None. 969491d8ee7SSantosh Puranik */ 970c21865c4SKonstantin Aladyshev 971c21865c4SKonstantin Aladyshev inline void 972ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 973491d8ee7SSantosh Puranik { 9741e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9751e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9761e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9771e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 978ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9791e1e598dSJonathan Doman const std::string& bootSourceStr) { 980491d8ee7SSantosh Puranik if (ec) 981491d8ee7SSantosh Puranik { 9825ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 9835ef735c8SNan Zhou { 9845ef735c8SNan Zhou return; 9855ef735c8SNan Zhou } 986b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 987ac106bf6SEd Tanous messages::internalError(asyncResp->res); 988491d8ee7SSantosh Puranik return; 989491d8ee7SSantosh Puranik } 990491d8ee7SSantosh Puranik 99162598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 992491d8ee7SSantosh Puranik 9931e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 994491d8ee7SSantosh Puranik if (!rfSource.empty()) 995491d8ee7SSantosh Puranik { 996ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 997ac106bf6SEd Tanous rfSource; 998491d8ee7SSantosh Puranik } 999cd9a4666SKonstantin Aladyshev 1000cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1001cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1002ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10031e1e598dSJonathan Doman }); 1004491d8ee7SSantosh Puranik } 1005491d8ee7SSantosh Puranik 1006491d8ee7SSantosh Puranik /** 1007c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1008c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1009c21865c4SKonstantin Aladyshev * state 1010491d8ee7SSantosh Puranik * 1011ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1012491d8ee7SSantosh Puranik * 1013491d8ee7SSantosh Puranik * @return None. 1014491d8ee7SSantosh Puranik */ 1015491d8ee7SSantosh Puranik 1016ac106bf6SEd Tanous inline void processBootOverrideEnable( 1017ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1018c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1019c21865c4SKonstantin Aladyshev { 1020c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1021c21865c4SKonstantin Aladyshev { 1022ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1023ac106bf6SEd Tanous "Disabled"; 1024c21865c4SKonstantin Aladyshev return; 1025c21865c4SKonstantin Aladyshev } 1026c21865c4SKonstantin Aladyshev 1027c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1028c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10291e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10301e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10311e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10321e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1033ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1034491d8ee7SSantosh Puranik if (ec) 1035491d8ee7SSantosh Puranik { 1036b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1037ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1038491d8ee7SSantosh Puranik return; 1039491d8ee7SSantosh Puranik } 1040491d8ee7SSantosh Puranik 1041c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1042c21865c4SKonstantin Aladyshev { 1043ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1044ac106bf6SEd Tanous "Once"; 1045c21865c4SKonstantin Aladyshev } 1046c21865c4SKonstantin Aladyshev else 1047c21865c4SKonstantin Aladyshev { 1048ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1049c21865c4SKonstantin Aladyshev "Continuous"; 1050c21865c4SKonstantin Aladyshev } 10511e1e598dSJonathan Doman }); 1052491d8ee7SSantosh Puranik } 1053491d8ee7SSantosh Puranik 1054491d8ee7SSantosh Puranik /** 1055c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1056c21865c4SKonstantin Aladyshev * 1057ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1058c21865c4SKonstantin Aladyshev * 1059c21865c4SKonstantin Aladyshev * @return None. 1060c21865c4SKonstantin Aladyshev */ 1061c21865c4SKonstantin Aladyshev 1062c21865c4SKonstantin Aladyshev inline void 1063ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1064c21865c4SKonstantin Aladyshev { 10651e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10661e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10671e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10681e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1069ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10701e1e598dSJonathan Doman const bool bootOverrideEnable) { 1071c21865c4SKonstantin Aladyshev if (ec) 1072c21865c4SKonstantin Aladyshev { 10735ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10745ef735c8SNan Zhou { 10755ef735c8SNan Zhou return; 10765ef735c8SNan Zhou } 1077b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1078ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1079c21865c4SKonstantin Aladyshev return; 1080c21865c4SKonstantin Aladyshev } 1081c21865c4SKonstantin Aladyshev 1082ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 10831e1e598dSJonathan Doman }); 1084c21865c4SKonstantin Aladyshev } 1085c21865c4SKonstantin Aladyshev 1086c21865c4SKonstantin Aladyshev /** 1087c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1088c21865c4SKonstantin Aladyshev * 1089ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1090c21865c4SKonstantin Aladyshev * 1091c21865c4SKonstantin Aladyshev * @return None. 1092c21865c4SKonstantin Aladyshev */ 1093ac106bf6SEd Tanous inline void 1094ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1095c21865c4SKonstantin Aladyshev { 109662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1097c21865c4SKonstantin Aladyshev 1098ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1099ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1100ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1101c21865c4SKonstantin Aladyshev } 1102c21865c4SKonstantin Aladyshev 1103c21865c4SKonstantin Aladyshev /** 1104c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1105c0557e1aSGunnar Mills * 1106c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1107c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1108c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1109c0557e1aSGunnar Mills * last power operation time. 1110c0557e1aSGunnar Mills * 1111ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1112c0557e1aSGunnar Mills * 1113c0557e1aSGunnar Mills * @return None. 1114c0557e1aSGunnar Mills */ 1115ac106bf6SEd Tanous inline void 1116ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1117c0557e1aSGunnar Mills { 111862598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1119c0557e1aSGunnar Mills 11201e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11211e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11221e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11231e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1124ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1125ac106bf6SEd Tanous uint64_t lastResetTime) { 1126c0557e1aSGunnar Mills if (ec) 1127c0557e1aSGunnar Mills { 112862598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1129c0557e1aSGunnar Mills return; 1130c0557e1aSGunnar Mills } 1131c0557e1aSGunnar Mills 1132c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1133c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11341e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1135c0557e1aSGunnar Mills 1136c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1137ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 11382b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11391e1e598dSJonathan Doman }); 1140c0557e1aSGunnar Mills } 1141c0557e1aSGunnar Mills 1142c0557e1aSGunnar Mills /** 1143797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1144797d5daeSCorey Hardesty * 1145797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1146797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1147797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1148797d5daeSCorey Hardesty * dbus. 1149797d5daeSCorey Hardesty * 1150ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1151797d5daeSCorey Hardesty * 1152797d5daeSCorey Hardesty * @return None. 1153797d5daeSCorey Hardesty */ 1154ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1155ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1156797d5daeSCorey Hardesty { 115762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1158797d5daeSCorey Hardesty 1159797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1160797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1161797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1162797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1163ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1164ac106bf6SEd Tanous const boost::system::error_code& ec, 1165797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1166797d5daeSCorey Hardesty if (ec) 1167797d5daeSCorey Hardesty { 1168797d5daeSCorey Hardesty if (ec.value() != EBADR) 1169797d5daeSCorey Hardesty { 117062598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1171ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1172797d5daeSCorey Hardesty } 1173797d5daeSCorey Hardesty return; 1174797d5daeSCorey Hardesty } 1175797d5daeSCorey Hardesty 1176797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1177797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1178797d5daeSCorey Hardesty 1179797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1180797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1181797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1182797d5daeSCorey Hardesty 1183797d5daeSCorey Hardesty if (!success) 1184797d5daeSCorey Hardesty { 1185ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1186797d5daeSCorey Hardesty return; 1187797d5daeSCorey Hardesty } 1188797d5daeSCorey Hardesty 1189797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1190797d5daeSCorey Hardesty { 1191ac106bf6SEd Tanous asyncResp->res 1192ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1193797d5daeSCorey Hardesty *attemptsLeft; 1194797d5daeSCorey Hardesty } 1195797d5daeSCorey Hardesty 1196797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1197797d5daeSCorey Hardesty { 1198ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1199797d5daeSCorey Hardesty *retryAttempts; 1200797d5daeSCorey Hardesty } 1201797d5daeSCorey Hardesty }); 1202797d5daeSCorey Hardesty } 1203797d5daeSCorey Hardesty 1204797d5daeSCorey Hardesty /** 12056bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12066bd5a8d2SGunnar Mills * 1207ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12086bd5a8d2SGunnar Mills * 12096bd5a8d2SGunnar Mills * @return None. 12106bd5a8d2SGunnar Mills */ 1211797d5daeSCorey Hardesty inline void 1212ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12136bd5a8d2SGunnar Mills { 121462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12156bd5a8d2SGunnar Mills 12161e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12171e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12181e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12191e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1220ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1221ac106bf6SEd Tanous bool autoRebootEnabled) { 12226bd5a8d2SGunnar Mills if (ec) 12236bd5a8d2SGunnar Mills { 1224797d5daeSCorey Hardesty if (ec.value() != EBADR) 1225797d5daeSCorey Hardesty { 122662598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1227ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1228797d5daeSCorey Hardesty } 12296bd5a8d2SGunnar Mills return; 12306bd5a8d2SGunnar Mills } 12316bd5a8d2SGunnar Mills 123262598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1233e05aec50SEd Tanous if (autoRebootEnabled) 12346bd5a8d2SGunnar Mills { 1235ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12366bd5a8d2SGunnar Mills "RetryAttempts"; 12376bd5a8d2SGunnar Mills } 12386bd5a8d2SGunnar Mills else 12396bd5a8d2SGunnar Mills { 1240ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1241ac106bf6SEd Tanous "Disabled"; 12426bd5a8d2SGunnar Mills } 1243ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 124469f35306SGunnar Mills 124569f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 124669f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 124769f35306SGunnar Mills // RetryAttempts. 1248ac106bf6SEd Tanous asyncResp->res 1249ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1250ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 12511e1e598dSJonathan Doman }); 12526bd5a8d2SGunnar Mills } 12536bd5a8d2SGunnar Mills 12546bd5a8d2SGunnar Mills /** 1255797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1256797d5daeSCorey Hardesty * 1257ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1258797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1259797d5daeSCorey Hardesty * 1260797d5daeSCorey Hardesty *@return None. 1261797d5daeSCorey Hardesty */ 1262797d5daeSCorey Hardesty 1263ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1264ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1265797d5daeSCorey Hardesty const uint32_t retryAttempts) 1266797d5daeSCorey Hardesty { 126762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 126887c44966SAsmitha Karunanithi setDbusProperty( 126987c44966SAsmitha Karunanithi asyncResp, "xyz.openbmc_project.State.Host", 127087c44966SAsmitha Karunanithi sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"), 12719ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 127287c44966SAsmitha Karunanithi "Boot/AutomaticRetryAttempts", retryAttempts); 1273797d5daeSCorey Hardesty } 1274797d5daeSCorey Hardesty 12758d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 12768d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 12778d69c668SEd Tanous { 12788d69c668SEd Tanous if (value == 12798d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 12808d69c668SEd Tanous { 12818d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 12828d69c668SEd Tanous } 12838d69c668SEd Tanous if (value == 12848d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 12858d69c668SEd Tanous { 12868d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 12878d69c668SEd Tanous } 12888d69c668SEd Tanous if (value == 12893a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 12908d69c668SEd Tanous { 12918d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 12928d69c668SEd Tanous } 12938d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 12948d69c668SEd Tanous { 12958d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 12968d69c668SEd Tanous } 12978d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 12988d69c668SEd Tanous } 1299797d5daeSCorey Hardesty /** 1300c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1301c6a620f2SGeorge Liu * 1302ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1303c6a620f2SGeorge Liu * 1304c6a620f2SGeorge Liu * @return None. 1305c6a620f2SGeorge Liu */ 13068d1b46d7Szhanghch05 inline void 1307ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1308c6a620f2SGeorge Liu { 130962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1310c6a620f2SGeorge Liu 13111e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13121e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13131e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13141e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1315ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13165e7e2dc5SEd Tanous const std::string& policy) { 1317c6a620f2SGeorge Liu if (ec) 1318c6a620f2SGeorge Liu { 131962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1320c6a620f2SGeorge Liu return; 1321c6a620f2SGeorge Liu } 13228d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 13238d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 13248d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1325c6a620f2SGeorge Liu { 1326ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1327c6a620f2SGeorge Liu return; 1328c6a620f2SGeorge Liu } 1329c6a620f2SGeorge Liu 13308d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 13311e1e598dSJonathan Doman }); 1332c6a620f2SGeorge Liu } 1333c6a620f2SGeorge Liu 1334c6a620f2SGeorge Liu /** 13359dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 13369dcfe8c1SAlbert Zhang * 13379dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 13389dcfe8c1SAlbert Zhang * 13399dcfe8c1SAlbert Zhang * @return None. 13409dcfe8c1SAlbert Zhang */ 13419dcfe8c1SAlbert Zhang inline void 13429dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13439dcfe8c1SAlbert Zhang { 134462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 13459dcfe8c1SAlbert Zhang 13469dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 13479dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13489dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 13499dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 13509dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 13519dcfe8c1SAlbert Zhang if (ec) 13529dcfe8c1SAlbert Zhang { 13539dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 13549dcfe8c1SAlbert Zhang { 1355b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 13569dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 13579dcfe8c1SAlbert Zhang } 13589dcfe8c1SAlbert Zhang return; 13599dcfe8c1SAlbert Zhang } 13609dcfe8c1SAlbert Zhang 13619dcfe8c1SAlbert Zhang if (value) 13629dcfe8c1SAlbert Zhang { 13639dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault"; 13649dcfe8c1SAlbert Zhang } 13659dcfe8c1SAlbert Zhang else 13669dcfe8c1SAlbert Zhang { 13679dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never"; 13689dcfe8c1SAlbert Zhang } 13699dcfe8c1SAlbert Zhang }); 13709dcfe8c1SAlbert Zhang } 13719dcfe8c1SAlbert Zhang 13729dcfe8c1SAlbert Zhang /** 13731981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13741981771bSAli Ahmed * TPM is required for booting the host. 13751981771bSAli Ahmed * 1376ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 13771981771bSAli Ahmed * 13781981771bSAli Ahmed * @return None. 13791981771bSAli Ahmed */ 13801981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1381ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13821981771bSAli Ahmed { 138362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1384e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1385e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1386e99073f5SGeorge Liu dbus::utility::getSubTree( 1387e99073f5SGeorge Liu "/", 0, interfaces, 1388ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1389b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 13901981771bSAli Ahmed if (ec) 13911981771bSAli Ahmed { 139262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", 139362598e31SEd Tanous ec); 13941981771bSAli Ahmed // This is an optional D-Bus object so just return if 13951981771bSAli Ahmed // error occurs 13961981771bSAli Ahmed return; 13971981771bSAli Ahmed } 139826f6976fSEd Tanous if (subtree.empty()) 13991981771bSAli Ahmed { 14001981771bSAli Ahmed // As noted above, this is an optional interface so just return 14011981771bSAli Ahmed // if there is no instance found 14021981771bSAli Ahmed return; 14031981771bSAli Ahmed } 14041981771bSAli Ahmed 14051981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14061981771bSAli Ahmed if (subtree.size() > 1) 14071981771bSAli Ahmed { 140862598e31SEd Tanous BMCWEB_LOG_DEBUG( 140962598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 141062598e31SEd Tanous subtree.size()); 14111981771bSAli Ahmed // Throw an internal Error and return 1412ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14131981771bSAli Ahmed return; 14141981771bSAli Ahmed } 14151981771bSAli Ahmed 14161981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14171981771bSAli Ahmed // field 14181981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14191981771bSAli Ahmed { 142062598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1421ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14221981771bSAli Ahmed return; 14231981771bSAli Ahmed } 14241981771bSAli Ahmed 14251981771bSAli Ahmed const std::string& path = subtree[0].first; 14261981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14271981771bSAli Ahmed 14281981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14291e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14301e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14311e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1432ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1433ac106bf6SEd Tanous bool tpmRequired) { 14348a592810SEd Tanous if (ec2) 14351981771bSAli Ahmed { 1436b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}", 143762598e31SEd Tanous ec2); 1438ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14391981771bSAli Ahmed return; 14401981771bSAli Ahmed } 14411981771bSAli Ahmed 14421e1e598dSJonathan Doman if (tpmRequired) 14431981771bSAli Ahmed { 1444ac106bf6SEd Tanous asyncResp->res 1445ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14461981771bSAli Ahmed "Required"; 14471981771bSAli Ahmed } 14481981771bSAli Ahmed else 14491981771bSAli Ahmed { 1450ac106bf6SEd Tanous asyncResp->res 1451ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14521981771bSAli Ahmed "Disabled"; 14531981771bSAli Ahmed } 14541e1e598dSJonathan Doman }); 1455e99073f5SGeorge Liu }); 14561981771bSAli Ahmed } 14571981771bSAli Ahmed 14581981771bSAli Ahmed /** 14591c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14601c05dae3SAli Ahmed * TPM is required for booting the host. 14611c05dae3SAli Ahmed * 1462ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14631c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14641c05dae3SAli Ahmed * 14651c05dae3SAli Ahmed * @return None. 14661c05dae3SAli Ahmed */ 14671c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1468ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 14691c05dae3SAli Ahmed { 147062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1471e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1472e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1473e99073f5SGeorge Liu dbus::utility::getSubTree( 1474e99073f5SGeorge Liu "/", 0, interfaces, 1475ac106bf6SEd Tanous [asyncResp, 1476e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1477e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 14781c05dae3SAli Ahmed if (ec) 14791c05dae3SAli Ahmed { 1480b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", 148162598e31SEd Tanous ec); 1482ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14831c05dae3SAli Ahmed return; 14841c05dae3SAli Ahmed } 148526f6976fSEd Tanous if (subtree.empty()) 14861c05dae3SAli Ahmed { 1487ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 14881c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 14891c05dae3SAli Ahmed return; 14901c05dae3SAli Ahmed } 14911c05dae3SAli Ahmed 14921c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 14931c05dae3SAli Ahmed if (subtree.size() > 1) 14941c05dae3SAli Ahmed { 149562598e31SEd Tanous BMCWEB_LOG_DEBUG( 149662598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 149762598e31SEd Tanous subtree.size()); 14981c05dae3SAli Ahmed // Throw an internal Error and return 1499ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15001c05dae3SAli Ahmed return; 15011c05dae3SAli Ahmed } 15021c05dae3SAli Ahmed 15031c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15041c05dae3SAli Ahmed // field 15051c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15061c05dae3SAli Ahmed { 150762598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1508ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15091c05dae3SAli Ahmed return; 15101c05dae3SAli Ahmed } 15111c05dae3SAli Ahmed 15121c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15131c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15141c05dae3SAli Ahmed 15151c05dae3SAli Ahmed if (serv.empty()) 15161c05dae3SAli Ahmed { 151762598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1518ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15191c05dae3SAli Ahmed return; 15201c05dae3SAli Ahmed } 15211c05dae3SAli Ahmed 15221c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 152387c44966SAsmitha Karunanithi setDbusProperty(asyncResp, serv, path, 152487c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 152587c44966SAsmitha Karunanithi "Boot/TrustedModuleRequiredToBoot", tpmRequired); 1526e99073f5SGeorge Liu }); 15271c05dae3SAli Ahmed } 15281c05dae3SAli Ahmed 15291c05dae3SAli Ahmed /** 1530491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1531491d8ee7SSantosh Puranik * 1532ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1533cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1534cd9a4666SKonstantin Aladyshev * @return Integer error code. 1535cd9a4666SKonstantin Aladyshev */ 1536ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1537cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1538cd9a4666SKonstantin Aladyshev { 1539c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1540cd9a4666SKonstantin Aladyshev 1541c21865c4SKonstantin Aladyshev if (!bootType) 1542cd9a4666SKonstantin Aladyshev { 1543c21865c4SKonstantin Aladyshev return; 1544c21865c4SKonstantin Aladyshev } 1545c21865c4SKonstantin Aladyshev 1546cd9a4666SKonstantin Aladyshev // Source target specified 154762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1548cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1549cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1550cd9a4666SKonstantin Aladyshev { 1551cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1552cd9a4666SKonstantin Aladyshev } 1553cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1554cd9a4666SKonstantin Aladyshev { 1555cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1556cd9a4666SKonstantin Aladyshev } 1557cd9a4666SKonstantin Aladyshev else 1558cd9a4666SKonstantin Aladyshev { 155962598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 156062598e31SEd Tanous "BootSourceOverrideMode: {}", 156162598e31SEd Tanous *bootType); 1562ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1563cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1564cd9a4666SKonstantin Aladyshev return; 1565cd9a4666SKonstantin Aladyshev } 1566cd9a4666SKonstantin Aladyshev 1567cd9a4666SKonstantin Aladyshev // Act on validated parameters 156862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1569cd9a4666SKonstantin Aladyshev 157087c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Settings", 157187c44966SAsmitha Karunanithi sdbusplus::message::object_path( 157287c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 157387c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Type", "BootType", 157487c44966SAsmitha Karunanithi "Boot/BootSourceOverrideMode", bootTypeStr); 1575cd9a4666SKonstantin Aladyshev } 1576cd9a4666SKonstantin Aladyshev 1577cd9a4666SKonstantin Aladyshev /** 1578cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1579cd9a4666SKonstantin Aladyshev * 1580ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1581ac106bf6SEd Tanous * message. 1582c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1583c21865c4SKonstantin Aladyshev * @return Integer error code. 1584c21865c4SKonstantin Aladyshev */ 1585ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1586c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1587c21865c4SKonstantin Aladyshev { 1588c21865c4SKonstantin Aladyshev if (!bootEnable) 1589c21865c4SKonstantin Aladyshev { 1590c21865c4SKonstantin Aladyshev return; 1591c21865c4SKonstantin Aladyshev } 1592c21865c4SKonstantin Aladyshev // Source target specified 159362598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1594c21865c4SKonstantin Aladyshev 1595c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1596c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1597c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1598c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1599c21865c4SKonstantin Aladyshev { 1600c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1601c21865c4SKonstantin Aladyshev } 1602c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1603c21865c4SKonstantin Aladyshev { 1604c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1605c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1606c21865c4SKonstantin Aladyshev } 1607c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1608c21865c4SKonstantin Aladyshev { 1609c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1610c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1611c21865c4SKonstantin Aladyshev } 1612c21865c4SKonstantin Aladyshev else 1613c21865c4SKonstantin Aladyshev { 161462598e31SEd Tanous BMCWEB_LOG_DEBUG( 161562598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 161662598e31SEd Tanous *bootEnable); 1617ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1618c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1619c21865c4SKonstantin Aladyshev return; 1620c21865c4SKonstantin Aladyshev } 1621c21865c4SKonstantin Aladyshev 1622c21865c4SKonstantin Aladyshev // Act on validated parameters 162362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1624c21865c4SKonstantin Aladyshev 162587c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Settings", 162687c44966SAsmitha Karunanithi sdbusplus::message::object_path( 162787c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 162887c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 162987c44966SAsmitha Karunanithi "Boot/BootSourceOverrideEnabled", bootOverrideEnable); 1630c21865c4SKonstantin Aladyshev 1631c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1632c21865c4SKonstantin Aladyshev { 1633c21865c4SKonstantin Aladyshev return; 1634c21865c4SKonstantin Aladyshev } 1635c21865c4SKonstantin Aladyshev 1636c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1637c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 163862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 163962598e31SEd Tanous bootOverridePersistent); 1640c21865c4SKonstantin Aladyshev 164187c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Settings", 164287c44966SAsmitha Karunanithi sdbusplus::message::object_path( 164387c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot/one_time"), 164487c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 164587c44966SAsmitha Karunanithi "Boot/BootSourceOverrideEnabled", !bootOverridePersistent); 1646c21865c4SKonstantin Aladyshev } 1647c21865c4SKonstantin Aladyshev 1648c21865c4SKonstantin Aladyshev /** 1649c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1650c21865c4SKonstantin Aladyshev * 1651ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1652491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1653491d8ee7SSantosh Puranik * 1654265c1602SJohnathan Mantey * @return Integer error code. 1655491d8ee7SSantosh Puranik */ 1656ac106bf6SEd Tanous inline void 1657ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1658cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1659491d8ee7SSantosh Puranik { 1660c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1661c21865c4SKonstantin Aladyshev std::string bootModeStr; 1662944ffaf9SJohnathan Mantey 1663c21865c4SKonstantin Aladyshev if (!bootSource) 1664491d8ee7SSantosh Puranik { 1665c21865c4SKonstantin Aladyshev return; 1666c21865c4SKonstantin Aladyshev } 1667c21865c4SKonstantin Aladyshev 1668491d8ee7SSantosh Puranik // Source target specified 166962598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1670491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1671ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1672ac106bf6SEd Tanous bootModeStr) != 0) 1673491d8ee7SSantosh Puranik { 167462598e31SEd Tanous BMCWEB_LOG_DEBUG( 167562598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 167662598e31SEd Tanous *bootSource); 1677ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1678491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1679491d8ee7SSantosh Puranik return; 1680491d8ee7SSantosh Puranik } 1681491d8ee7SSantosh Puranik 1682944ffaf9SJohnathan Mantey // Act on validated parameters 168362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 168462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1685944ffaf9SJohnathan Mantey 168687c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Settings", 168787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 168887c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 168987c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Source", "BootSource", 169087c44966SAsmitha Karunanithi "Boot/BootSourceOverrideTarget", bootSourceStr); 169187c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Settings", 169287c44966SAsmitha Karunanithi sdbusplus::message::object_path( 169387c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 169487c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 169587c44966SAsmitha Karunanithi "Boot/BootSourceOverrideTarget", bootModeStr); 1696cd9a4666SKonstantin Aladyshev } 1697944ffaf9SJohnathan Mantey 1698cd9a4666SKonstantin Aladyshev /** 1699c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1700491d8ee7SSantosh Puranik * 1701ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1702491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1703cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1704491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1705491d8ee7SSantosh Puranik * 1706265c1602SJohnathan Mantey * @return Integer error code. 1707491d8ee7SSantosh Puranik */ 1708c21865c4SKonstantin Aladyshev 1709ac106bf6SEd Tanous inline void 1710ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1711c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1712c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1713c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1714491d8ee7SSantosh Puranik { 171562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1716491d8ee7SSantosh Puranik 1717ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1718ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1719ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1720491d8ee7SSantosh Puranik } 1721491d8ee7SSantosh Puranik 1722c6a620f2SGeorge Liu /** 172398e386ecSGunnar Mills * @brief Sets AssetTag 172498e386ecSGunnar Mills * 1725ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 172698e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 172798e386ecSGunnar Mills * 172898e386ecSGunnar Mills * @return None. 172998e386ecSGunnar Mills */ 1730ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 173198e386ecSGunnar Mills const std::string& assetTag) 173298e386ecSGunnar Mills { 1733e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1734e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1735e99073f5SGeorge Liu dbus::utility::getSubTree( 1736e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1737ac106bf6SEd Tanous [asyncResp, 1738e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1739b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 174098e386ecSGunnar Mills if (ec) 174198e386ecSGunnar Mills { 174262598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1743ac106bf6SEd Tanous messages::internalError(asyncResp->res); 174498e386ecSGunnar Mills return; 174598e386ecSGunnar Mills } 174626f6976fSEd Tanous if (subtree.empty()) 174798e386ecSGunnar Mills { 174862598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1749ac106bf6SEd Tanous messages::internalError(asyncResp->res); 175098e386ecSGunnar Mills return; 175198e386ecSGunnar Mills } 175298e386ecSGunnar Mills // Assume only 1 system D-Bus object 175398e386ecSGunnar Mills // Throw an error if there is more than 1 175498e386ecSGunnar Mills if (subtree.size() > 1) 175598e386ecSGunnar Mills { 175662598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1757ac106bf6SEd Tanous messages::internalError(asyncResp->res); 175898e386ecSGunnar Mills return; 175998e386ecSGunnar Mills } 176098e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 176198e386ecSGunnar Mills { 176262598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1763ac106bf6SEd Tanous messages::internalError(asyncResp->res); 176498e386ecSGunnar Mills return; 176598e386ecSGunnar Mills } 176698e386ecSGunnar Mills 176798e386ecSGunnar Mills const std::string& path = subtree[0].first; 176898e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 176998e386ecSGunnar Mills 177098e386ecSGunnar Mills if (service.empty()) 177198e386ecSGunnar Mills { 177262598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1773ac106bf6SEd Tanous messages::internalError(asyncResp->res); 177498e386ecSGunnar Mills return; 177598e386ecSGunnar Mills } 177698e386ecSGunnar Mills 177787c44966SAsmitha Karunanithi setDbusProperty(asyncResp, service, path, 177887c44966SAsmitha Karunanithi "xyz.openbmc_project.Inventory.Decorator.AssetTag", 177987c44966SAsmitha Karunanithi "AssetTag", "AssetTag", assetTag); 1780e99073f5SGeorge Liu }); 178198e386ecSGunnar Mills } 178298e386ecSGunnar Mills 178398e386ecSGunnar Mills /** 17849dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 17859dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 17869dcfe8c1SAlbert Zhang * 17879dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 17889dcfe8c1SAlbert Zhang * stopBootOnFault 17899dcfe8c1SAlbert Zhang * 17909dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 17919dcfe8c1SAlbert Zhang */ 17929dcfe8c1SAlbert Zhang inline std::optional<bool> 17939dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 17949dcfe8c1SAlbert Zhang { 17959dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 17969dcfe8c1SAlbert Zhang { 17979dcfe8c1SAlbert Zhang return true; 17989dcfe8c1SAlbert Zhang } 17999dcfe8c1SAlbert Zhang 18009dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 18019dcfe8c1SAlbert Zhang { 18029dcfe8c1SAlbert Zhang return false; 18039dcfe8c1SAlbert Zhang } 18049dcfe8c1SAlbert Zhang 18059dcfe8c1SAlbert Zhang return std::nullopt; 18069dcfe8c1SAlbert Zhang } 18079dcfe8c1SAlbert Zhang 18089dcfe8c1SAlbert Zhang /** 18099dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 18109dcfe8c1SAlbert Zhang * 1811fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 18129dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 18139dcfe8c1SAlbert Zhang * 18149dcfe8c1SAlbert Zhang * @return None. 18159dcfe8c1SAlbert Zhang */ 1816fc3edfddSEd Tanous inline void 1817fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 18189dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 18199dcfe8c1SAlbert Zhang { 182062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 18219dcfe8c1SAlbert Zhang 18229dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 18239dcfe8c1SAlbert Zhang if (!stopBootEnabled) 18249dcfe8c1SAlbert Zhang { 182562598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 182662598e31SEd Tanous stopBootOnFault); 1827fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 18289dcfe8c1SAlbert Zhang "StopBootOnFault"); 18299dcfe8c1SAlbert Zhang return; 18309dcfe8c1SAlbert Zhang } 18319dcfe8c1SAlbert Zhang 183287c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Settings", 183387c44966SAsmitha Karunanithi sdbusplus::message::object_path( 183487c44966SAsmitha Karunanithi "/xyz/openbmc_project/logging/settings"), 1835fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 183687c44966SAsmitha Karunanithi "Boot/StopBootOnFault", *stopBootEnabled); 18379dcfe8c1SAlbert Zhang } 18389dcfe8c1SAlbert Zhang 18399dcfe8c1SAlbert Zhang /** 184069f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 184169f35306SGunnar Mills * 1842ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 184369f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 184469f35306SGunnar Mills * 184569f35306SGunnar Mills * @return None. 184669f35306SGunnar Mills */ 1847ac106bf6SEd Tanous inline void 1848ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1849f23b7296SEd Tanous const std::string& automaticRetryConfig) 185069f35306SGunnar Mills { 185162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 185269f35306SGunnar Mills 185369f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1854543f4400SEd Tanous bool autoRebootEnabled = false; 185569f35306SGunnar Mills 185669f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 185769f35306SGunnar Mills { 185869f35306SGunnar Mills autoRebootEnabled = false; 185969f35306SGunnar Mills } 186069f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 186169f35306SGunnar Mills { 186269f35306SGunnar Mills autoRebootEnabled = true; 186369f35306SGunnar Mills } 186469f35306SGunnar Mills else 186569f35306SGunnar Mills { 186662598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 186762598e31SEd Tanous automaticRetryConfig); 1868ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 186969f35306SGunnar Mills "AutomaticRetryConfig"); 187069f35306SGunnar Mills return; 187169f35306SGunnar Mills } 187269f35306SGunnar Mills 187387c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Settings", 187487c44966SAsmitha Karunanithi sdbusplus::message::object_path( 187587c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/auto_reboot"), 187687c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.RebootPolicy", 187787c44966SAsmitha Karunanithi "AutoReboot", "Boot/AutomaticRetryConfig", 187887c44966SAsmitha Karunanithi autoRebootEnabled); 187969f35306SGunnar Mills } 188069f35306SGunnar Mills 18818d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 18828d69c668SEd Tanous { 18838d69c668SEd Tanous if (policy == "AlwaysOn") 18848d69c668SEd Tanous { 18858d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 18868d69c668SEd Tanous } 18878d69c668SEd Tanous if (policy == "AlwaysOff") 18888d69c668SEd Tanous { 18898d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 18908d69c668SEd Tanous } 18918d69c668SEd Tanous if (policy == "LastState") 18928d69c668SEd Tanous { 18938d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 18948d69c668SEd Tanous } 18958d69c668SEd Tanous return ""; 18968d69c668SEd Tanous } 18978d69c668SEd Tanous 189869f35306SGunnar Mills /** 1899c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1900c6a620f2SGeorge Liu * 1901ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1902c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1903c6a620f2SGeorge Liu * 1904c6a620f2SGeorge Liu * @return None. 1905c6a620f2SGeorge Liu */ 19068d1b46d7Szhanghch05 inline void 1907ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19088d69c668SEd Tanous std::string_view policy) 1909c6a620f2SGeorge Liu { 191062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 1911c6a620f2SGeorge Liu 19128d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 1913c6a620f2SGeorge Liu 19148d69c668SEd Tanous if (powerRestorePolicy.empty()) 1915c6a620f2SGeorge Liu { 1916ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 19174e69c904SGunnar Mills "PowerRestorePolicy"); 1918c6a620f2SGeorge Liu return; 1919c6a620f2SGeorge Liu } 1920c6a620f2SGeorge Liu 192187c44966SAsmitha Karunanithi setDbusProperty( 192287c44966SAsmitha Karunanithi asyncResp, "xyz.openbmc_project.Settings", 192387c44966SAsmitha Karunanithi sdbusplus::message::object_path( 192487c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/power_restore_policy"), 19259ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 192687c44966SAsmitha Karunanithi "PowerRestorePolicy", powerRestorePolicy); 1927c6a620f2SGeorge Liu } 1928c6a620f2SGeorge Liu 1929a6349918SAppaRao Puli /** 1930a6349918SAppaRao Puli * @brief Retrieves provisioning status 1931a6349918SAppaRao Puli * 193225b54dbaSEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous 193325b54dbaSEd Tanous * calls. 1934a6349918SAppaRao Puli * 1935a6349918SAppaRao Puli * @return None. 1936a6349918SAppaRao Puli */ 193725b54dbaSEd Tanous inline void 193825b54dbaSEd Tanous getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1939a6349918SAppaRao Puli { 194062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 1941bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1942bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1943bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 1944ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1945b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1946b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1947ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 1948ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 194950626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 195050626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 195150626f4fSJames Feist 1952a6349918SAppaRao Puli if (ec) 1953a6349918SAppaRao Puli { 195462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1955b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1956b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1957a6349918SAppaRao Puli return; 1958a6349918SAppaRao Puli } 1959a6349918SAppaRao Puli 1960a6349918SAppaRao Puli const bool* provState = nullptr; 1961a6349918SAppaRao Puli const bool* lockState = nullptr; 1962bc1d29deSKrzysztof Grobelny 1963bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 19640d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 19650d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 1966bc1d29deSKrzysztof Grobelny 1967bc1d29deSKrzysztof Grobelny if (!success) 1968a6349918SAppaRao Puli { 1969ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1970bc1d29deSKrzysztof Grobelny return; 1971a6349918SAppaRao Puli } 1972a6349918SAppaRao Puli 1973a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 1974a6349918SAppaRao Puli { 197562598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 1976ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1977a6349918SAppaRao Puli return; 1978a6349918SAppaRao Puli } 1979a6349918SAppaRao Puli 198025b54dbaSEd Tanous if (*provState) 1981a6349918SAppaRao Puli { 198225b54dbaSEd Tanous if (*lockState) 1983a6349918SAppaRao Puli { 1984a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 1985a6349918SAppaRao Puli } 1986a6349918SAppaRao Puli else 1987a6349918SAppaRao Puli { 1988a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 1989a6349918SAppaRao Puli } 1990a6349918SAppaRao Puli } 1991a6349918SAppaRao Puli else 1992a6349918SAppaRao Puli { 1993a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1994a6349918SAppaRao Puli } 1995bc1d29deSKrzysztof Grobelny }); 1996a6349918SAppaRao Puli } 1997a6349918SAppaRao Puli 1998491d8ee7SSantosh Puranik /** 19996b9ac4f2SChris Cain * @brief Translate the PowerMode string to enum value 20003a2d0424SChris Cain * 20016b9ac4f2SChris Cain * @param[in] modeString PowerMode string to be translated 20023a2d0424SChris Cain * 20036b9ac4f2SChris Cain * @return PowerMode enum 20043a2d0424SChris Cain */ 20056b9ac4f2SChris Cain inline computer_system::PowerMode 20066b9ac4f2SChris Cain translatePowerModeString(const std::string& modeString) 20073a2d0424SChris Cain { 2008b6655101SChris Cain using PowerMode = computer_system::PowerMode; 2009b6655101SChris Cain 20106b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20113a2d0424SChris Cain { 20126b9ac4f2SChris Cain return PowerMode::Static; 20133a2d0424SChris Cain } 20146b9ac4f2SChris Cain if (modeString == 20150fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20163a2d0424SChris Cain { 20176b9ac4f2SChris Cain return PowerMode::MaximumPerformance; 20183a2d0424SChris Cain } 20196b9ac4f2SChris Cain if (modeString == 20200fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20213a2d0424SChris Cain { 20226b9ac4f2SChris Cain return PowerMode::PowerSaving; 2023b6655101SChris Cain } 20246b9ac4f2SChris Cain if (modeString == 2025b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance") 2026b6655101SChris Cain { 20276b9ac4f2SChris Cain return PowerMode::BalancedPerformance; 2028b6655101SChris Cain } 20296b9ac4f2SChris Cain if (modeString == 2030b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance") 2031b6655101SChris Cain { 20326b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPerformance; 2033b6655101SChris Cain } 20346b9ac4f2SChris Cain if (modeString == 2035b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower") 2036b6655101SChris Cain { 20376b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPower; 20383a2d0424SChris Cain } 20396b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20403a2d0424SChris Cain { 20416b9ac4f2SChris Cain return PowerMode::OEM; 20426b9ac4f2SChris Cain } 20436b9ac4f2SChris Cain // Any other values would be invalid 20446b9ac4f2SChris Cain BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString); 20456b9ac4f2SChris Cain return PowerMode::Invalid; 20466b9ac4f2SChris Cain } 20476b9ac4f2SChris Cain 20486b9ac4f2SChris Cain inline void 20496b9ac4f2SChris Cain afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20506b9ac4f2SChris Cain const boost::system::error_code& ec, 20516b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) 20526b9ac4f2SChris Cain { 20536b9ac4f2SChris Cain if (ec) 20546b9ac4f2SChris Cain { 20556b9ac4f2SChris Cain BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec); 20566b9ac4f2SChris Cain messages::internalError(asyncResp->res); 20576b9ac4f2SChris Cain return; 20586b9ac4f2SChris Cain } 20596b9ac4f2SChris Cain 20606b9ac4f2SChris Cain std::string powerMode; 20616b9ac4f2SChris Cain const std::vector<std::string>* allowedModes = nullptr; 20626b9ac4f2SChris Cain const bool success = sdbusplus::unpackPropertiesNoThrow( 20636b9ac4f2SChris Cain dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode, 20646b9ac4f2SChris Cain "AllowedPowerModes", allowedModes); 20656b9ac4f2SChris Cain 20666b9ac4f2SChris Cain if (!success) 20676b9ac4f2SChris Cain { 20686b9ac4f2SChris Cain messages::internalError(asyncResp->res); 20696b9ac4f2SChris Cain return; 20706b9ac4f2SChris Cain } 20716b9ac4f2SChris Cain 20726b9ac4f2SChris Cain nlohmann::json::array_t modeList; 20736b9ac4f2SChris Cain if (allowedModes == nullptr) 20746b9ac4f2SChris Cain { 20756b9ac4f2SChris Cain modeList.emplace_back("Static"); 20766b9ac4f2SChris Cain modeList.emplace_back("MaximumPerformance"); 20776b9ac4f2SChris Cain modeList.emplace_back("PowerSaving"); 20783a2d0424SChris Cain } 20793a2d0424SChris Cain else 20803a2d0424SChris Cain { 20816b9ac4f2SChris Cain for (const auto& aMode : *allowedModes) 20826b9ac4f2SChris Cain { 20836b9ac4f2SChris Cain computer_system::PowerMode modeValue = 20846b9ac4f2SChris Cain translatePowerModeString(aMode); 20856b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 20866b9ac4f2SChris Cain { 2087ac106bf6SEd Tanous messages::internalError(asyncResp->res); 20886b9ac4f2SChris Cain continue; 20896b9ac4f2SChris Cain } 20906b9ac4f2SChris Cain modeList.emplace_back(modeValue); 20913a2d0424SChris Cain } 20923a2d0424SChris Cain } 20936b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList; 20943a2d0424SChris Cain 20956b9ac4f2SChris Cain BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode); 20966b9ac4f2SChris Cain const computer_system::PowerMode modeValue = 20976b9ac4f2SChris Cain translatePowerModeString(powerMode); 20986b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 20996b9ac4f2SChris Cain { 21006b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21016b9ac4f2SChris Cain return; 21026b9ac4f2SChris Cain } 21036b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode"] = modeValue; 21046b9ac4f2SChris Cain } 21053a2d0424SChris Cain /** 21063a2d0424SChris Cain * @brief Retrieves system power mode 21073a2d0424SChris Cain * 2108ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21093a2d0424SChris Cain * 21103a2d0424SChris Cain * @return None. 21113a2d0424SChris Cain */ 2112ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 21133a2d0424SChris Cain { 211462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 21153a2d0424SChris Cain 21163a2d0424SChris Cain // Get Power Mode object path: 2117e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2118e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2119e99073f5SGeorge Liu dbus::utility::getSubTree( 2120e99073f5SGeorge Liu "/", 0, interfaces, 2121ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2122b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21233a2d0424SChris Cain if (ec) 21243a2d0424SChris Cain { 212562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}", 212662598e31SEd Tanous ec); 21273a2d0424SChris Cain // This is an optional D-Bus object so just return if 21283a2d0424SChris Cain // error occurs 21293a2d0424SChris Cain return; 21303a2d0424SChris Cain } 21313a2d0424SChris Cain if (subtree.empty()) 21323a2d0424SChris Cain { 21333a2d0424SChris Cain // As noted above, this is an optional interface so just return 21343a2d0424SChris Cain // if there is no instance found 21353a2d0424SChris Cain return; 21363a2d0424SChris Cain } 21373a2d0424SChris Cain if (subtree.size() > 1) 21383a2d0424SChris Cain { 21393a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21403a2d0424SChris Cain // error 214162598e31SEd Tanous BMCWEB_LOG_DEBUG( 214262598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 214362598e31SEd Tanous subtree.size()); 2144ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21453a2d0424SChris Cain return; 21463a2d0424SChris Cain } 21473a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21483a2d0424SChris Cain { 214962598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2150ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21513a2d0424SChris Cain return; 21523a2d0424SChris Cain } 21533a2d0424SChris Cain const std::string& path = subtree[0].first; 21543a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21553a2d0424SChris Cain if (service.empty()) 21563a2d0424SChris Cain { 215762598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2158ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21593a2d0424SChris Cain return; 21603a2d0424SChris Cain } 21616b9ac4f2SChris Cain 21626b9ac4f2SChris Cain // Valid Power Mode object found, now read the mode properties 21636b9ac4f2SChris Cain sdbusplus::asio::getAllProperties( 21641e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 21656b9ac4f2SChris Cain "xyz.openbmc_project.Control.Power.Mode", 2166ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 21676b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 21686b9ac4f2SChris Cain afterGetPowerMode(asyncResp, ec2, properties); 21691e1e598dSJonathan Doman }); 2170e99073f5SGeorge Liu }); 21713a2d0424SChris Cain } 21723a2d0424SChris Cain 21733a2d0424SChris Cain /** 21743a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21753a2d0424SChris Cain * name associated with that string 21763a2d0424SChris Cain * 2177ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2178b6655101SChris Cain * @param[in] modeValue String representing the desired PowerMode 21793a2d0424SChris Cain * 21803a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 21813a2d0424SChris Cain */ 21823a2d0424SChris Cain inline std::string 2183ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2184b6655101SChris Cain const nlohmann::json& modeValue) 21853a2d0424SChris Cain { 2186b6655101SChris Cain using PowerMode = computer_system::PowerMode; 21873a2d0424SChris Cain std::string mode; 21883a2d0424SChris Cain 2189b6655101SChris Cain if (modeValue == PowerMode::Static) 21903a2d0424SChris Cain { 21913a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 21923a2d0424SChris Cain } 2193b6655101SChris Cain else if (modeValue == PowerMode::MaximumPerformance) 21943a2d0424SChris Cain { 21950fda0f12SGeorge Liu mode = 21960fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 21973a2d0424SChris Cain } 2198b6655101SChris Cain else if (modeValue == PowerMode::PowerSaving) 21993a2d0424SChris Cain { 22003a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22013a2d0424SChris Cain } 2202b6655101SChris Cain else if (modeValue == PowerMode::BalancedPerformance) 2203b6655101SChris Cain { 2204b6655101SChris Cain mode = 2205b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance"; 2206b6655101SChris Cain } 2207b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPerformance) 2208b6655101SChris Cain { 2209b6655101SChris Cain mode = 2210b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance"; 2211b6655101SChris Cain } 2212b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPower) 2213b6655101SChris Cain { 2214b6655101SChris Cain mode = 2215b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower"; 2216b6655101SChris Cain } 22173a2d0424SChris Cain else 22183a2d0424SChris Cain { 2219b6655101SChris Cain messages::propertyValueNotInList(asyncResp->res, modeValue.dump(), 2220ac106bf6SEd Tanous "PowerMode"); 22213a2d0424SChris Cain } 22223a2d0424SChris Cain return mode; 22233a2d0424SChris Cain } 22243a2d0424SChris Cain 22253a2d0424SChris Cain /** 22263a2d0424SChris Cain * @brief Sets system power mode. 22273a2d0424SChris Cain * 2228ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22293a2d0424SChris Cain * @param[in] pmode System power mode from request. 22303a2d0424SChris Cain * 22313a2d0424SChris Cain * @return None. 22323a2d0424SChris Cain */ 2233ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22343a2d0424SChris Cain const std::string& pmode) 22353a2d0424SChris Cain { 223662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 22373a2d0424SChris Cain 2238ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 22393a2d0424SChris Cain if (powerMode.empty()) 22403a2d0424SChris Cain { 22413a2d0424SChris Cain return; 22423a2d0424SChris Cain } 22433a2d0424SChris Cain 22443a2d0424SChris Cain // Get Power Mode object path: 2245e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2246e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2247e99073f5SGeorge Liu dbus::utility::getSubTree( 2248e99073f5SGeorge Liu "/", 0, interfaces, 2249ac106bf6SEd Tanous [asyncResp, 2250e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2251b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22523a2d0424SChris Cain if (ec) 22533a2d0424SChris Cain { 2254b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}", 225562598e31SEd Tanous ec); 22563a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2257ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22583a2d0424SChris Cain return; 22593a2d0424SChris Cain } 22603a2d0424SChris Cain if (subtree.empty()) 22613a2d0424SChris Cain { 22623a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2263ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 22643a2d0424SChris Cain "PowerMode"); 22653a2d0424SChris Cain return; 22663a2d0424SChris Cain } 22673a2d0424SChris Cain if (subtree.size() > 1) 22683a2d0424SChris Cain { 22693a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22703a2d0424SChris Cain // error 227162598e31SEd Tanous BMCWEB_LOG_DEBUG( 227262598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 227362598e31SEd Tanous subtree.size()); 2274ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22753a2d0424SChris Cain return; 22763a2d0424SChris Cain } 22773a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22783a2d0424SChris Cain { 227962598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2280ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22813a2d0424SChris Cain return; 22823a2d0424SChris Cain } 22833a2d0424SChris Cain const std::string& path = subtree[0].first; 22843a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22853a2d0424SChris Cain if (service.empty()) 22863a2d0424SChris Cain { 228762598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2288ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22893a2d0424SChris Cain return; 22903a2d0424SChris Cain } 22913a2d0424SChris Cain 229262598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 22933a2d0424SChris Cain 22943a2d0424SChris Cain // Set the Power Mode property 229587c44966SAsmitha Karunanithi setDbusProperty(asyncResp, service, path, 229687c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 229787c44966SAsmitha Karunanithi "PowerMode", powerMode); 2298e99073f5SGeorge Liu }); 22993a2d0424SChris Cain } 23003a2d0424SChris Cain 23013a2d0424SChris Cain /** 230251709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 230351709ffdSYong Li * 230451709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 230551709ffdSYong Li * 230651709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 230751709ffdSYong Li * translation cannot be done, returns an empty string. 230851709ffdSYong Li */ 230923a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 231051709ffdSYong Li { 231151709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 231251709ffdSYong Li { 231351709ffdSYong Li return "None"; 231451709ffdSYong Li } 23153174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 231651709ffdSYong Li { 231751709ffdSYong Li return "ResetSystem"; 231851709ffdSYong Li } 23193174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 232051709ffdSYong Li { 232151709ffdSYong Li return "PowerDown"; 232251709ffdSYong Li } 23233174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 232451709ffdSYong Li { 232551709ffdSYong Li return "PowerCycle"; 232651709ffdSYong Li } 232751709ffdSYong Li 232851709ffdSYong Li return ""; 232951709ffdSYong Li } 233051709ffdSYong Li 233151709ffdSYong Li /** 2332c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2333c45f0082SYong Li * 2334c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2335c45f0082SYong Li * 2336c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2337c45f0082SYong Li *If translation cannot be done, returns an empty string. 2338c45f0082SYong Li */ 2339c45f0082SYong Li 234023a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2341c45f0082SYong Li { 2342c45f0082SYong Li if (rfAction == "None") 2343c45f0082SYong Li { 2344c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2345c45f0082SYong Li } 23463174e4dfSEd Tanous if (rfAction == "PowerCycle") 2347c45f0082SYong Li { 2348c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2349c45f0082SYong Li } 23503174e4dfSEd Tanous if (rfAction == "PowerDown") 2351c45f0082SYong Li { 2352c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2353c45f0082SYong Li } 23543174e4dfSEd Tanous if (rfAction == "ResetSystem") 2355c45f0082SYong Li { 2356c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2357c45f0082SYong Li } 2358c45f0082SYong Li 2359c45f0082SYong Li return ""; 2360c45f0082SYong Li } 2361c45f0082SYong Li 2362c45f0082SYong Li /** 236351709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 236451709ffdSYong Li * 2365ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 236651709ffdSYong Li * 236751709ffdSYong Li * @return None. 236851709ffdSYong Li */ 23698d1b46d7Szhanghch05 inline void 2370ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 237151709ffdSYong Li { 237262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2373bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2374bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2375bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2376bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2377ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2378b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 237951709ffdSYong Li if (ec) 238051709ffdSYong Li { 238151709ffdSYong Li // watchdog service is stopped 238262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 238351709ffdSYong Li return; 238451709ffdSYong Li } 238551709ffdSYong Li 238662598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 238751709ffdSYong Li 238851709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2389ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 239051709ffdSYong Li 239151709ffdSYong Li // watchdog service is running/enabled 239251709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 239351709ffdSYong Li 2394bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2395bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 239651709ffdSYong Li 2397bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2398bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2399bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2400bc1d29deSKrzysztof Grobelny 2401bc1d29deSKrzysztof Grobelny if (!success) 240251709ffdSYong Li { 2403ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2404601af5edSChicago Duan return; 240551709ffdSYong Li } 240651709ffdSYong Li 2407bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 240851709ffdSYong Li { 2409bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 241051709ffdSYong Li } 241151709ffdSYong Li 2412bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2413bc1d29deSKrzysztof Grobelny { 2414bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 241551709ffdSYong Li if (action.empty()) 241651709ffdSYong Li { 2417ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2418601af5edSChicago Duan return; 241951709ffdSYong Li } 242051709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 242151709ffdSYong Li } 2422bc1d29deSKrzysztof Grobelny }); 242351709ffdSYong Li } 242451709ffdSYong Li 242551709ffdSYong Li /** 2426c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2427c45f0082SYong Li * 2428ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2429c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2430c45f0082SYong Li * RF request. 2431c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2432c45f0082SYong Li * 2433c45f0082SYong Li * @return None. 2434c45f0082SYong Li */ 2435ac106bf6SEd Tanous inline void 2436ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2437c45f0082SYong Li const std::optional<bool> wdtEnable, 2438c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2439c45f0082SYong Li { 244062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2441c45f0082SYong Li 2442c45f0082SYong Li if (wdtTimeOutAction) 2443c45f0082SYong Li { 2444c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2445c45f0082SYong Li // check if TimeOut Action is Valid 2446c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2447c45f0082SYong Li { 244862598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 244962598e31SEd Tanous *wdtTimeOutAction); 2450ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2451c45f0082SYong Li "TimeoutAction"); 2452c45f0082SYong Li return; 2453c45f0082SYong Li } 2454c45f0082SYong Li 245587c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Watchdog", 245687c44966SAsmitha Karunanithi sdbusplus::message::object_path( 245787c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 24589ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 245987c44966SAsmitha Karunanithi "HostWatchdogTimer/TimeoutAction", wdtTimeOutActStr); 2460c45f0082SYong Li } 2461c45f0082SYong Li 2462c45f0082SYong Li if (wdtEnable) 2463c45f0082SYong Li { 246487c44966SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Watchdog", 246587c44966SAsmitha Karunanithi sdbusplus::message::object_path( 246687c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 246787c44966SAsmitha Karunanithi "xyz.openbmc_project.State.Watchdog", "Enabled", 246887c44966SAsmitha Karunanithi "HostWatchdogTimer/FunctionEnabled", *wdtEnable); 2469c45f0082SYong Li } 2470c45f0082SYong Li } 2471c45f0082SYong Li 247237bbf98cSChris Cain /** 247337bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 247437bbf98cSChris Cain * 2475ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 247637bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 247737bbf98cSChris Cain * 247837bbf98cSChris Cain * @return true if successful 247937bbf98cSChris Cain */ 24801e5b7c88SJiaqing Zhao inline bool 2481ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 24821e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 248337bbf98cSChris Cain { 2484bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2485bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2486bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2487bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2488bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2489bc1d29deSKrzysztof Grobelny 2490bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2491bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 24922661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 24932661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 24942661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2495bc1d29deSKrzysztof Grobelny 2496bc1d29deSKrzysztof Grobelny if (!success) 249737bbf98cSChris Cain { 249837bbf98cSChris Cain return false; 249937bbf98cSChris Cain } 2500bc1d29deSKrzysztof Grobelny 2501bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 250237bbf98cSChris Cain { 2503ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 250437bbf98cSChris Cain } 2505bc1d29deSKrzysztof Grobelny 2506bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 250737bbf98cSChris Cain { 2508ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2509bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 251037bbf98cSChris Cain } 2511bc1d29deSKrzysztof Grobelny 2512bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2513bc1d29deSKrzysztof Grobelny { 2514bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2515ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 251637bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 251737bbf98cSChris Cain .count(); 251837bbf98cSChris Cain } 2519bc1d29deSKrzysztof Grobelny 2520bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 252137bbf98cSChris Cain { 2522ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2523bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 252437bbf98cSChris Cain } 2525bc1d29deSKrzysztof Grobelny 2526bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 252737bbf98cSChris Cain { 2528bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2529ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 253037bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 253137bbf98cSChris Cain .count(); 253237bbf98cSChris Cain } 253337bbf98cSChris Cain 253437bbf98cSChris Cain return true; 253537bbf98cSChris Cain } 253637bbf98cSChris Cain 253737bbf98cSChris Cain /** 253837bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 253937bbf98cSChris Cain * 2540ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 254137bbf98cSChris Cain * 254237bbf98cSChris Cain * @return None. 254337bbf98cSChris Cain */ 2544ac106bf6SEd Tanous inline void 2545ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 254637bbf98cSChris Cain { 254762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 254837bbf98cSChris Cain 254937bbf98cSChris Cain // Get IdlePowerSaver object path: 2550e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2551e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2552e99073f5SGeorge Liu dbus::utility::getSubTree( 2553e99073f5SGeorge Liu "/", 0, interfaces, 2554ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2555b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 255637bbf98cSChris Cain if (ec) 255737bbf98cSChris Cain { 2558b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 255962598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 256062598e31SEd Tanous ec); 2561ac106bf6SEd Tanous messages::internalError(asyncResp->res); 256237bbf98cSChris Cain return; 256337bbf98cSChris Cain } 256437bbf98cSChris Cain if (subtree.empty()) 256537bbf98cSChris Cain { 256637bbf98cSChris Cain // This is an optional interface so just return 256737bbf98cSChris Cain // if there is no instance found 256862598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 256937bbf98cSChris Cain return; 257037bbf98cSChris Cain } 257137bbf98cSChris Cain if (subtree.size() > 1) 257237bbf98cSChris Cain { 257337bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 257437bbf98cSChris Cain // is an error 257562598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 257662598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 257762598e31SEd Tanous subtree.size()); 2578ac106bf6SEd Tanous messages::internalError(asyncResp->res); 257937bbf98cSChris Cain return; 258037bbf98cSChris Cain } 258137bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 258237bbf98cSChris Cain { 258362598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2584ac106bf6SEd Tanous messages::internalError(asyncResp->res); 258537bbf98cSChris Cain return; 258637bbf98cSChris Cain } 258737bbf98cSChris Cain const std::string& path = subtree[0].first; 258837bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 258937bbf98cSChris Cain if (service.empty()) 259037bbf98cSChris Cain { 259162598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2592ac106bf6SEd Tanous messages::internalError(asyncResp->res); 259337bbf98cSChris Cain return; 259437bbf98cSChris Cain } 259537bbf98cSChris Cain 259637bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2597bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2598bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2599bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2600ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 26011e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 26028a592810SEd Tanous if (ec2) 260337bbf98cSChris Cain { 260462598e31SEd Tanous BMCWEB_LOG_ERROR( 260562598e31SEd Tanous "DBUS response error on IdlePowerSaver GetAll: {}", ec2); 2606ac106bf6SEd Tanous messages::internalError(asyncResp->res); 260737bbf98cSChris Cain return; 260837bbf98cSChris Cain } 260937bbf98cSChris Cain 2610ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 261137bbf98cSChris Cain { 2612ac106bf6SEd Tanous messages::internalError(asyncResp->res); 261337bbf98cSChris Cain return; 261437bbf98cSChris Cain } 2615bc1d29deSKrzysztof Grobelny }); 2616e99073f5SGeorge Liu }); 261737bbf98cSChris Cain 261862598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 261937bbf98cSChris Cain } 262037bbf98cSChris Cain 262137bbf98cSChris Cain /** 262237bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 262337bbf98cSChris Cain * 2624ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 262537bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 262637bbf98cSChris Cain * RF request. 262737bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 262837bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 262937bbf98cSChris Cain * before entering idle state. 263037bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 263137bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 263237bbf98cSChris Cain * before exiting idle state 263337bbf98cSChris Cain * 263437bbf98cSChris Cain * @return None. 263537bbf98cSChris Cain */ 2636ac106bf6SEd Tanous inline void 2637ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 263837bbf98cSChris Cain const std::optional<bool> ipsEnable, 263937bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 264037bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 264137bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 264237bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 264337bbf98cSChris Cain { 264462598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 264537bbf98cSChris Cain 264637bbf98cSChris Cain // Get IdlePowerSaver object path: 2647e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2648e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2649e99073f5SGeorge Liu dbus::utility::getSubTree( 2650e99073f5SGeorge Liu "/", 0, interfaces, 2651ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2652e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2653b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 265437bbf98cSChris Cain if (ec) 265537bbf98cSChris Cain { 2656b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 265762598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 265862598e31SEd Tanous ec); 2659ac106bf6SEd Tanous messages::internalError(asyncResp->res); 266037bbf98cSChris Cain return; 266137bbf98cSChris Cain } 266237bbf98cSChris Cain if (subtree.empty()) 266337bbf98cSChris Cain { 266437bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2665ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 266637bbf98cSChris Cain "IdlePowerSaver"); 266737bbf98cSChris Cain return; 266837bbf98cSChris Cain } 266937bbf98cSChris Cain if (subtree.size() > 1) 267037bbf98cSChris Cain { 267137bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 267237bbf98cSChris Cain // is an error 267362598e31SEd Tanous BMCWEB_LOG_DEBUG( 267462598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 267562598e31SEd Tanous subtree.size()); 2676ac106bf6SEd Tanous messages::internalError(asyncResp->res); 267737bbf98cSChris Cain return; 267837bbf98cSChris Cain } 267937bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 268037bbf98cSChris Cain { 268162598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2682ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268337bbf98cSChris Cain return; 268437bbf98cSChris Cain } 268537bbf98cSChris Cain const std::string& path = subtree[0].first; 268637bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 268737bbf98cSChris Cain if (service.empty()) 268837bbf98cSChris Cain { 268962598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2690ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269137bbf98cSChris Cain return; 269237bbf98cSChris Cain } 269337bbf98cSChris Cain 269437bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 269537bbf98cSChris Cain // need to be updated 269637bbf98cSChris Cain 269737bbf98cSChris Cain if (ipsEnable) 269837bbf98cSChris Cain { 269987c44966SAsmitha Karunanithi setDbusProperty(asyncResp, service, path, 270087c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Power.IdlePowerSaver", 270187c44966SAsmitha Karunanithi "Enabled", "IdlePowerSaver/Enabled", *ipsEnable); 270237bbf98cSChris Cain } 270337bbf98cSChris Cain if (ipsEnterUtil) 270437bbf98cSChris Cain { 270587c44966SAsmitha Karunanithi setDbusProperty(asyncResp, service, path, 27069ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 270787c44966SAsmitha Karunanithi "EnterUtilizationPercent", 270887c44966SAsmitha Karunanithi "IdlePowerSaver/EnterUtilizationPercent", 270987c44966SAsmitha Karunanithi *ipsEnterUtil); 271037bbf98cSChris Cain } 271137bbf98cSChris Cain if (ipsEnterTime) 271237bbf98cSChris Cain { 271337bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 271437bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 271587c44966SAsmitha Karunanithi setDbusProperty(asyncResp, service, path, 27169ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 271787c44966SAsmitha Karunanithi "EnterDwellTime", 271887c44966SAsmitha Karunanithi "IdlePowerSaver/EnterDwellTimeSeconds", 271987c44966SAsmitha Karunanithi timeMilliseconds); 272037bbf98cSChris Cain } 272137bbf98cSChris Cain if (ipsExitUtil) 272237bbf98cSChris Cain { 272387c44966SAsmitha Karunanithi setDbusProperty(asyncResp, service, path, 27249ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 272587c44966SAsmitha Karunanithi "ExitUtilizationPercent", 272687c44966SAsmitha Karunanithi "IdlePowerSaver/ExitUtilizationPercent", 272787c44966SAsmitha Karunanithi *ipsExitUtil); 272837bbf98cSChris Cain } 272937bbf98cSChris Cain if (ipsExitTime) 273037bbf98cSChris Cain { 273137bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 273237bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 273387c44966SAsmitha Karunanithi setDbusProperty(asyncResp, service, path, 27349ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 273587c44966SAsmitha Karunanithi "ExitDwellTime", 273687c44966SAsmitha Karunanithi "IdlePowerSaver/ExitDwellTimeSeconds", 273787c44966SAsmitha Karunanithi timeMilliseconds); 273837bbf98cSChris Cain } 2739e99073f5SGeorge Liu }); 274037bbf98cSChris Cain 274162598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 274237bbf98cSChris Cain } 274337bbf98cSChris Cain 2744c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2745dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2746dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2747dd60b9edSEd Tanous { 2748dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2749dd60b9edSEd Tanous { 2750dd60b9edSEd Tanous return; 2751dd60b9edSEd Tanous } 2752dd60b9edSEd Tanous asyncResp->res.addHeader( 2753dd60b9edSEd Tanous boost::beast::http::field::link, 2754dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2755dd60b9edSEd Tanous } 2756dd60b9edSEd Tanous 2757c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2758c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2759c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 27601abe55efSEd Tanous { 27613ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2762f4c99e70SEd Tanous { 2763f4c99e70SEd Tanous return; 2764f4c99e70SEd Tanous } 2765dd60b9edSEd Tanous 2766dd60b9edSEd Tanous asyncResp->res.addHeader( 2767dd60b9edSEd Tanous boost::beast::http::field::link, 2768dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 27698d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 27700f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 27718d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 27728d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2773462023adSSunitha Harish 27747f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 27757f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 277625b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 27777f3e84a1SEd Tanous { 27787f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 27797f3e84a1SEd Tanous // Option currently returns no systems. TBD 27807f3e84a1SEd Tanous return; 27817f3e84a1SEd Tanous } 27827f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 27837f3e84a1SEd Tanous nlohmann::json::object_t system; 2784*253f11b8SEd Tanous system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}", 2785*253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 27867f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 27871e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2788002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 27891e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2790002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 27915e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 27921e1e598dSJonathan Doman const std::string& /*hostName*/) { 27937f3e84a1SEd Tanous if (ec2) 2794462023adSSunitha Harish { 27957f3e84a1SEd Tanous return; 27967f3e84a1SEd Tanous } 27977f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 27987f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 27997f3e84a1SEd Tanous { 280062598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 28017f3e84a1SEd Tanous return; 28027f3e84a1SEd Tanous } 28037f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 28047f3e84a1SEd Tanous if (count == nullptr) 28057f3e84a1SEd Tanous { 280662598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 28077f3e84a1SEd Tanous return; 28087f3e84a1SEd Tanous } 28097f3e84a1SEd Tanous *count = *count + 1; 281062598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 28117f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 28121476687dSEd Tanous nlohmann::json::object_t hypervisor; 2813002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 28147f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 28151e1e598dSJonathan Doman }); 2816c1e219d5SEd Tanous } 2817c1e219d5SEd Tanous 2818c1e219d5SEd Tanous /** 28197e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28207e860f15SJohn Edward Broadbent */ 28214f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28227e860f15SJohn Edward Broadbent { 282389492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 282489492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 282589492a15SPatrick Williams constexpr const char* interfaceName = 28267e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 282789492a15SPatrick Williams constexpr const char* method = "NMI"; 28287e860f15SJohn Edward Broadbent 28297e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28305e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28317e860f15SJohn Edward Broadbent if (ec) 28327e860f15SJohn Edward Broadbent { 283362598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 28347e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28357e860f15SJohn Edward Broadbent return; 28367e860f15SJohn Edward Broadbent } 28377e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28387e860f15SJohn Edward Broadbent }, 28397e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28407e860f15SJohn Edward Broadbent } 2841c5b2abe0SLewanczyk, Dawid 2842c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2843c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 28447f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2845c1e219d5SEd Tanous const std::string& systemName) 2846c1e219d5SEd Tanous { 28473ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 284845ca1b86SEd Tanous { 284945ca1b86SEd Tanous return; 285045ca1b86SEd Tanous } 2851*253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 2852c1e219d5SEd Tanous { 2853c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2854c1e219d5SEd Tanous systemName); 2855c1e219d5SEd Tanous return; 2856c1e219d5SEd Tanous } 285725b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 28587f3e84a1SEd Tanous { 28597f3e84a1SEd Tanous // Option currently returns no systems. TBD 28607f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2861c1e219d5SEd Tanous systemName); 28627f3e84a1SEd Tanous return; 28637f3e84a1SEd Tanous } 28649712f8acSEd Tanous std::string resetType; 2865c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 2866cc340dd9SEd Tanous { 2867cc340dd9SEd Tanous return; 2868cc340dd9SEd Tanous } 2869cc340dd9SEd Tanous 2870d22c8396SJason M. Bills // Get the command and host vs. chassis 2871cc340dd9SEd Tanous std::string command; 2872543f4400SEd Tanous bool hostCommand = true; 2873d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2874cc340dd9SEd Tanous { 2875cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2876d22c8396SJason M. Bills hostCommand = true; 2877d22c8396SJason M. Bills } 2878d22c8396SJason M. Bills else if (resetType == "ForceOff") 2879d22c8396SJason M. Bills { 2880d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2881d22c8396SJason M. Bills hostCommand = false; 2882d22c8396SJason M. Bills } 2883d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2884d22c8396SJason M. Bills { 2885c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 288686a0851aSJason M. Bills hostCommand = true; 2887cc340dd9SEd Tanous } 28889712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2889cc340dd9SEd Tanous { 2890cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2891d22c8396SJason M. Bills hostCommand = true; 2892cc340dd9SEd Tanous } 28939712f8acSEd Tanous else if (resetType == "GracefulRestart") 2894cc340dd9SEd Tanous { 28950fda0f12SGeorge Liu command = 28960fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2897d22c8396SJason M. Bills hostCommand = true; 2898d22c8396SJason M. Bills } 2899d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2900d22c8396SJason M. Bills { 290186a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 290286a0851aSJason M. Bills hostCommand = true; 2903cc340dd9SEd Tanous } 2904bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2905bfd5b826SLakshminarayana R. Kammath { 2906bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2907bfd5b826SLakshminarayana R. Kammath return; 2908bfd5b826SLakshminarayana R. Kammath } 2909cc340dd9SEd Tanous else 2910cc340dd9SEd Tanous { 2911c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 2912cc340dd9SEd Tanous return; 2913cc340dd9SEd Tanous } 2914d02aad39SEd Tanous sdbusplus::message::object_path statePath("/xyz/openbmc_project/state"); 2915cc340dd9SEd Tanous 2916d22c8396SJason M. Bills if (hostCommand) 2917d22c8396SJason M. Bills { 2918d02aad39SEd Tanous setDbusProperty(asyncResp, "xyz.openbmc_project.State.Host", 2919d02aad39SEd Tanous statePath / "host0", "xyz.openbmc_project.State.Host", 2920d02aad39SEd Tanous "RequestedHostTransition", "Reset", command); 2921cc340dd9SEd Tanous } 2922d22c8396SJason M. Bills else 2923d22c8396SJason M. Bills { 2924d02aad39SEd Tanous setDbusProperty(asyncResp, "xyz.openbmc_project.State.Chassis", 2925d02aad39SEd Tanous statePath / "chassis0", 2926d02aad39SEd Tanous "xyz.openbmc_project.State.Chassis", 2927d02aad39SEd Tanous "RequestedPowerTransition", "Reset", command); 2928d22c8396SJason M. Bills } 2929d22c8396SJason M. Bills } 2930cc340dd9SEd Tanous 2931c1e219d5SEd Tanous inline void handleComputerSystemHead( 2932dd60b9edSEd Tanous App& app, const crow::Request& req, 29337f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29347f3e84a1SEd Tanous const std::string& /*systemName*/) 2935dd60b9edSEd Tanous { 2936dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2937dd60b9edSEd Tanous { 2938dd60b9edSEd Tanous return; 2939dd60b9edSEd Tanous } 2940dd60b9edSEd Tanous 2941dd60b9edSEd Tanous asyncResp->res.addHeader( 2942dd60b9edSEd Tanous boost::beast::http::field::link, 2943dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2944dd60b9edSEd Tanous } 2945dd60b9edSEd Tanous 29465c3e9272SAbhishek Patel inline void afterPortRequest( 29475c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29485c3e9272SAbhishek Patel const boost::system::error_code& ec, 29495c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 29505c3e9272SAbhishek Patel { 29515c3e9272SAbhishek Patel if (ec) 29525c3e9272SAbhishek Patel { 2953b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 29545c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29555c3e9272SAbhishek Patel return; 29565c3e9272SAbhishek Patel } 29575c3e9272SAbhishek Patel for (const auto& data : socketData) 29585c3e9272SAbhishek Patel { 29595c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 29605c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 29615c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 29625c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 29635c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 29645c3e9272SAbhishek Patel // need to retrieve port number for 29655c3e9272SAbhishek Patel // obmc-console-ssh service 29665c3e9272SAbhishek Patel if (protocolName == "SSH") 29675c3e9272SAbhishek Patel { 29685c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 296981c4e330SEd Tanous const boost::system::error_code& ec1, 29705c3e9272SAbhishek Patel int portNumber) { 29715c3e9272SAbhishek Patel if (ec1) 29725c3e9272SAbhishek Patel { 2973b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 29745c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29755c3e9272SAbhishek Patel return; 29765c3e9272SAbhishek Patel } 29775c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 29785c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 29795c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 29805c3e9272SAbhishek Patel }); 29815c3e9272SAbhishek Patel } 29825c3e9272SAbhishek Patel } 29835c3e9272SAbhishek Patel } 2984c1e219d5SEd Tanous 2985c1e219d5SEd Tanous inline void 2986c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 298722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2988c1e219d5SEd Tanous const std::string& systemName) 2989c1e219d5SEd Tanous { 29903ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 299145ca1b86SEd Tanous { 299245ca1b86SEd Tanous return; 299345ca1b86SEd Tanous } 2994746b56f3SAsmitha Karunanithi 299525b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 29967f3e84a1SEd Tanous { 29977f3e84a1SEd Tanous // Option currently returns no systems. TBD 29987f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 29997f3e84a1SEd Tanous systemName); 30007f3e84a1SEd Tanous return; 30017f3e84a1SEd Tanous } 30027f3e84a1SEd Tanous 3003746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3004746b56f3SAsmitha Karunanithi { 3005746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3006746b56f3SAsmitha Karunanithi return; 3007746b56f3SAsmitha Karunanithi } 3008746b56f3SAsmitha Karunanithi 3009*253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 301022d268cbSEd Tanous { 301122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 301222d268cbSEd Tanous systemName); 301322d268cbSEd Tanous return; 301422d268cbSEd Tanous } 3015dd60b9edSEd Tanous asyncResp->res.addHeader( 3016dd60b9edSEd Tanous boost::beast::http::field::link, 3017dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 30188d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3019b6655101SChris Cain "#ComputerSystem.v1_22_0.ComputerSystem"; 3020*253f11b8SEd Tanous asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3021*253f11b8SEd Tanous asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 30228d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 30238d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 30248d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 3025cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3026dfb2b408SPriyanga Ramasamy double(0); 3027*253f11b8SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 3028*253f11b8SEd Tanous "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME); 302904a258f4SEd Tanous 3030*253f11b8SEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format( 3031*253f11b8SEd Tanous "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3032*253f11b8SEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format( 3033*253f11b8SEd Tanous "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3034*253f11b8SEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format( 3035*253f11b8SEd Tanous "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME); 30363179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 3037*253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters", 3038*253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3039029573d4SEd Tanous 3040002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 3041*253f11b8SEd Tanous boost::urls::format( 3042*253f11b8SEd Tanous "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", 3043*253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3044c1e219d5SEd Tanous asyncResp->res 3045c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 3046*253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3047*253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3048c5b2abe0SLewanczyk, Dawid 3049*253f11b8SEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format( 3050*253f11b8SEd Tanous "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3051*253f11b8SEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format( 3052*253f11b8SEd Tanous "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3053c4bf6374SJason M. Bills 30541476687dSEd Tanous nlohmann::json::array_t managedBy; 30551476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 3056*253f11b8SEd Tanous manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}", 3057*253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME); 3058002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 30591476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 30601476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 30610e8ac5e7SGunnar Mills 30620e8ac5e7SGunnar Mills // Fill in SerialConsole info 3063002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3064c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 30651476687dSEd Tanous 3066c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 30671476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3068c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 30691476687dSEd Tanous "Press ~. to exit console"; 30705c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 30715c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 30720e8ac5e7SGunnar Mills 307325b54dbaSEd Tanous if constexpr (BMCWEB_KVM) 307425b54dbaSEd Tanous { 30750e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3076002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 307725b54dbaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 307825b54dbaSEd Tanous 4; 3079613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3080613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 308125b54dbaSEd Tanous } 308213451e39SWilly Tu 3083002d39b4SEd Tanous getMainChassisId(asyncResp, 3084002d39b4SEd Tanous [](const std::string& chassisId, 30858d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3086b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3087b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3088ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3089ef4c65b7SEd Tanous chassisId); 3090002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3091c5d03ff4SJennifer Lee }); 3092a3002228SAppaRao Puli 309359a17e4fSGeorge Liu getSystemLocationIndicatorActive(asyncResp); 30949f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3095a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 309651bd2d8aSGunnar Mills getComputerSystem(asyncResp); 30976c34de48SEd Tanous getHostState(asyncResp); 3098491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3099978b8803SAndrew Geissler getBootProgress(asyncResp); 3100b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 310170c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 310270c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 310351709ffdSYong Li getHostWatchdogTimer(asyncResp); 3104c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 31059dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3106797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3107c0557e1aSGunnar Mills getLastResetTime(asyncResp); 310825b54dbaSEd Tanous if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE) 310925b54dbaSEd Tanous { 3110a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 311125b54dbaSEd Tanous } 31121981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 31133a2d0424SChris Cain getPowerMode(asyncResp); 311437bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3115c1e219d5SEd Tanous } 3116550a6bf8SJiaqing Zhao 3117c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3118c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 311922d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3120c1e219d5SEd Tanous const std::string& systemName) 3121c1e219d5SEd Tanous { 31223ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 312345ca1b86SEd Tanous { 312445ca1b86SEd Tanous return; 312545ca1b86SEd Tanous } 312625b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 31277f3e84a1SEd Tanous { 31287f3e84a1SEd Tanous // Option currently returns no systems. TBD 31297f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31307f3e84a1SEd Tanous systemName); 31317f3e84a1SEd Tanous return; 31327f3e84a1SEd Tanous } 3133*253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 313422d268cbSEd Tanous { 313522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 313622d268cbSEd Tanous systemName); 313722d268cbSEd Tanous return; 313822d268cbSEd Tanous } 313922d268cbSEd Tanous 3140dd60b9edSEd Tanous asyncResp->res.addHeader( 3141dd60b9edSEd Tanous boost::beast::http::field::link, 3142dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3143dd60b9edSEd Tanous 31449f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3145cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 314698e386ecSGunnar Mills std::optional<std::string> assetTag; 3147c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 31483a2d0424SChris Cain std::optional<std::string> powerMode; 3149550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3150550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3151550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3152550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3153550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3154550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3155797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3156550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 31579dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3158550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3159550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3160550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3161550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3162550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3163550a6bf8SJiaqing Zhao 3164550a6bf8SJiaqing Zhao // clang-format off 316515ed6780SWilly Tu if (!json_util::readJsonPatch( 3166550a6bf8SJiaqing Zhao req, asyncResp->res, 3167550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 31687e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3169550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3170550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3171550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3172550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3173550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3174550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3175550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3176550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3177550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3178797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3179550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 31809dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3181550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3182550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3183550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3184550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3185550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 31866617338dSEd Tanous { 31876617338dSEd Tanous return; 31886617338dSEd Tanous } 3189550a6bf8SJiaqing Zhao // clang-format on 3190491d8ee7SSantosh Puranik 31918d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3192c45f0082SYong Li 319398e386ecSGunnar Mills if (assetTag) 319498e386ecSGunnar Mills { 319598e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 319698e386ecSGunnar Mills } 319798e386ecSGunnar Mills 3198550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3199c45f0082SYong Li { 3200f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3201c45f0082SYong Li } 3202c45f0082SYong Li 3203cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 320469f35306SGunnar Mills { 3205002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3206491d8ee7SSantosh Puranik } 3207550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 320869f35306SGunnar Mills { 3209550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 321069f35306SGunnar Mills } 3211ac7e1e0bSAli Ahmed 3212797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3213797d5daeSCorey Hardesty { 3214797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3215797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3216797d5daeSCorey Hardesty } 3217797d5daeSCorey Hardesty 3218550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3219ac7e1e0bSAli Ahmed { 3220c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 322169f35306SGunnar Mills } 3222265c1602SJohnathan Mantey 32239dcfe8c1SAlbert Zhang if (stopBootOnFault) 32249dcfe8c1SAlbert Zhang { 32259dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 32269dcfe8c1SAlbert Zhang } 32279dcfe8c1SAlbert Zhang 32289f8bfa7cSGunnar Mills if (locationIndicatorActive) 32299f8bfa7cSGunnar Mills { 323059a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 32319f8bfa7cSGunnar Mills } 32329f8bfa7cSGunnar Mills 32337e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32347e860f15SJohn Edward Broadbent // passed 32359712f8acSEd Tanous if (indicatorLed) 32366617338dSEd Tanous { 3237f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3238002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3239d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3240d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32416617338dSEd Tanous } 3242c6a620f2SGeorge Liu 3243c6a620f2SGeorge Liu if (powerRestorePolicy) 3244c6a620f2SGeorge Liu { 32454e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3246c6a620f2SGeorge Liu } 32473a2d0424SChris Cain 32483a2d0424SChris Cain if (powerMode) 32493a2d0424SChris Cain { 32503a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32513a2d0424SChris Cain } 325237bbf98cSChris Cain 3253c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 325437bbf98cSChris Cain { 3255002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3256002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 325737bbf98cSChris Cain } 3258c1e219d5SEd Tanous } 32591cb1a9e6SAppaRao Puli 326038c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3261dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 32627f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3263c1e219d5SEd Tanous const std::string& /*systemName*/) 3264dd60b9edSEd Tanous { 3265dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3266dd60b9edSEd Tanous { 3267dd60b9edSEd Tanous return; 3268dd60b9edSEd Tanous } 3269dd60b9edSEd Tanous asyncResp->res.addHeader( 3270dd60b9edSEd Tanous boost::beast::http::field::link, 3271dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3272dd60b9edSEd Tanous } 327333e1f122SAndrew Geissler 327433e1f122SAndrew Geissler /** 327533e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 327633e1f122SAndrew Geissler * 327733e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 327833e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 327933e1f122SAndrew Geissler * 328033e1f122SAndrew Geissler * @return Emplaces correpsonding Redfish translated value(s) in 328133e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 328233e1f122SAndrew Geissler * allowableValues. 328333e1f122SAndrew Geissler */ 328433e1f122SAndrew Geissler inline void 328533e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran, 328633e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 328733e1f122SAndrew Geissler { 328833e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 328933e1f122SAndrew Geissler { 329033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 329133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 329233e1f122SAndrew Geissler } 329333e1f122SAndrew Geissler else if (dbusAllowedHostTran == 329433e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 329533e1f122SAndrew Geissler { 329633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 329733e1f122SAndrew Geissler } 329833e1f122SAndrew Geissler else if (dbusAllowedHostTran == 329933e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 330033e1f122SAndrew Geissler { 330133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 330233e1f122SAndrew Geissler } 330333e1f122SAndrew Geissler else if (dbusAllowedHostTran == 330433e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 330533e1f122SAndrew Geissler { 330633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 330733e1f122SAndrew Geissler } 330833e1f122SAndrew Geissler else 330933e1f122SAndrew Geissler { 331033e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 331133e1f122SAndrew Geissler } 331233e1f122SAndrew Geissler } 331333e1f122SAndrew Geissler 331433e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 331533e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 331633e1f122SAndrew Geissler const boost::system::error_code& ec, 331733e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 331833e1f122SAndrew Geissler { 331933e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 332033e1f122SAndrew Geissler 332133e1f122SAndrew Geissler // Supported on all systems currently 332233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 332333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 332433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 332533e1f122SAndrew Geissler 332633e1f122SAndrew Geissler if (ec) 332733e1f122SAndrew Geissler { 3328e715d14bSEd Tanous if ((ec.value() == 3329e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3330e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 333133e1f122SAndrew Geissler { 333233e1f122SAndrew Geissler // Property not implemented so just return defaults 333333e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 333433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 333533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 333633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 333733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 333833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 333933e1f122SAndrew Geissler } 334033e1f122SAndrew Geissler else 334133e1f122SAndrew Geissler { 334233e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 334333e1f122SAndrew Geissler messages::internalError(asyncResp->res); 334433e1f122SAndrew Geissler return; 334533e1f122SAndrew Geissler } 334633e1f122SAndrew Geissler } 334733e1f122SAndrew Geissler else 334833e1f122SAndrew Geissler { 334933e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 335033e1f122SAndrew Geissler { 335133e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 335233e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 335333e1f122SAndrew Geissler } 335433e1f122SAndrew Geissler } 335533e1f122SAndrew Geissler 335633e1f122SAndrew Geissler nlohmann::json::object_t parameter; 335733e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 335833e1f122SAndrew Geissler parameter["Required"] = true; 335933e1f122SAndrew Geissler parameter["DataType"] = "String"; 336033e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 336133e1f122SAndrew Geissler nlohmann::json::array_t parameters; 336233e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 336333e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 336433e1f122SAndrew Geissler } 336533e1f122SAndrew Geissler 3366c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3367c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 336822d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3369c1e219d5SEd Tanous const std::string& systemName) 3370c1e219d5SEd Tanous { 33713ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 337245ca1b86SEd Tanous { 337345ca1b86SEd Tanous return; 337445ca1b86SEd Tanous } 337525b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 33767f3e84a1SEd Tanous { 33777f3e84a1SEd Tanous // Option currently returns no systems. TBD 33787f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 33797f3e84a1SEd Tanous systemName); 33807f3e84a1SEd Tanous return; 33817f3e84a1SEd Tanous } 3382746b56f3SAsmitha Karunanithi 3383746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3384746b56f3SAsmitha Karunanithi { 3385746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3386746b56f3SAsmitha Karunanithi return; 3387746b56f3SAsmitha Karunanithi } 3388746b56f3SAsmitha Karunanithi 3389*253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 339022d268cbSEd Tanous { 339122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 339222d268cbSEd Tanous systemName); 339322d268cbSEd Tanous return; 339422d268cbSEd Tanous } 339522d268cbSEd Tanous 3396dd60b9edSEd Tanous asyncResp->res.addHeader( 3397dd60b9edSEd Tanous boost::beast::http::field::link, 3398dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 33991476687dSEd Tanous 34001476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 3401*253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3402*253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3403c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34041476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34051476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34063215e700SNan Zhou 340733e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 340833e1f122SAndrew Geissler sdbusplus::asio::getProperty<std::vector<std::string>>( 340933e1f122SAndrew Geissler *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 341033e1f122SAndrew Geissler "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 341133e1f122SAndrew Geissler "AllowedHostTransitions", 341233e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 341333e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 341433e1f122SAndrew Geissler afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions); 341533e1f122SAndrew Geissler }); 3416c1e219d5SEd Tanous } 3417c1e219d5SEd Tanous /** 3418c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3419c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3420c1e219d5SEd Tanous */ 3421100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3422c1e219d5SEd Tanous { 3423100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3424100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3425100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3426100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3427100afe56SEd Tanous 3428100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3429100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3430100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3431100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3432100afe56SEd Tanous 3433100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3434100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3435100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3436100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3437100afe56SEd Tanous 3438100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3439100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3440100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3441100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3442100afe56SEd Tanous 3443100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3444100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3445100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3446100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3447100afe56SEd Tanous 3448100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3449100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3450100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3451100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3452100afe56SEd Tanous 3453c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3454c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3455c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3456c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3457c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3458c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3459c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3460c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 34611cb1a9e6SAppaRao Puli } 3462c5b2abe0SLewanczyk, Dawid } // namespace redfish 3463