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 183ccb3adbSEd Tanous #include "app.hpp" 191e1e598dSJonathan Doman #include "dbus_singleton.hpp" 207a1dbc48SGeorge Liu #include "dbus_utility.hpp" 21b49ac873SJames Feist #include "health.hpp" 221c8fba97SJames Feist #include "led.hpp" 23f5c9f8bdSJason M. Bills #include "pcie.hpp" 24f4c99e70SEd Tanous #include "query.hpp" 25c5d03ff4SJennifer Lee #include "redfish_util.hpp" 263ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 273ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 283ccb3adbSEd Tanous #include "utils/json_utils.hpp" 293ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 302b82937eSEd Tanous #include "utils/time_utils.hpp" 31c5d03ff4SJennifer Lee 329712f8acSEd Tanous #include <boost/container/flat_map.hpp> 33e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 341e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 35bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 361214b7e7SGunnar Mills 377a1dbc48SGeorge Liu #include <array> 387a1dbc48SGeorge Liu #include <string_view> 39abf2add6SEd Tanous #include <variant> 40c5b2abe0SLewanczyk, Dawid 411abe55efSEd Tanous namespace redfish 421abe55efSEd Tanous { 43c5b2abe0SLewanczyk, Dawid 449d3ae10eSAlpana Kumari /** 459d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 469d3ae10eSAlpana Kumari * 479d3ae10eSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 489d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 499d3ae10eSAlpana Kumari * 509d3ae10eSAlpana Kumari * @return None. 519d3ae10eSAlpana Kumari */ 528d1b46d7Szhanghch05 inline void 538d1b46d7Szhanghch05 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 541e1e598dSJonathan Doman bool isDimmFunctional) 559d3ae10eSAlpana Kumari { 561e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional; 579d3ae10eSAlpana Kumari 589d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 599d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 609d3ae10eSAlpana Kumari // ENABLED. 6102cad96eSEd Tanous const nlohmann::json& prevMemSummary = 629d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 639d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 649d3ae10eSAlpana Kumari { 65e05aec50SEd Tanous if (isDimmFunctional) 669d3ae10eSAlpana Kumari { 679d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 689d3ae10eSAlpana Kumari "Enabled"; 699d3ae10eSAlpana Kumari } 709d3ae10eSAlpana Kumari } 719d3ae10eSAlpana Kumari } 729d3ae10eSAlpana Kumari 7357e8c9beSAlpana Kumari /* 7457e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 7557e8c9beSAlpana Kumari * 7657e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 7757e8c9beSAlpana Kumari * @param[in] cpuPresenceState CPU present or not 7857e8c9beSAlpana Kumari * 7957e8c9beSAlpana Kumari * @return None. 8057e8c9beSAlpana Kumari */ 811e1e598dSJonathan Doman inline void 821e1e598dSJonathan Doman modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 831e1e598dSJonathan Doman bool isCpuPresent) 8457e8c9beSAlpana Kumari { 851e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent; 8657e8c9beSAlpana Kumari 8755f79e6fSEd Tanous if (isCpuPresent) 8857e8c9beSAlpana Kumari { 89b4b9595aSJames Feist nlohmann::json& procCount = 90b4b9595aSJames Feist aResp->res.jsonValue["ProcessorSummary"]["Count"]; 9155f79e6fSEd Tanous auto* procCountPtr = 92b4b9595aSJames Feist procCount.get_ptr<nlohmann::json::number_integer_t*>(); 93b4b9595aSJames Feist if (procCountPtr != nullptr) 94b4b9595aSJames Feist { 95b4b9595aSJames Feist // shouldn't be possible to be nullptr 96b4b9595aSJames Feist *procCountPtr += 1; 9757e8c9beSAlpana Kumari } 98b4b9595aSJames Feist } 9957e8c9beSAlpana Kumari } 10057e8c9beSAlpana Kumari 10157e8c9beSAlpana Kumari /* 10257e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 10357e8c9beSAlpana Kumari * CPU Functional State 10457e8c9beSAlpana Kumari * 10557e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 10657e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 10757e8c9beSAlpana Kumari * 10857e8c9beSAlpana Kumari * @return None. 10957e8c9beSAlpana Kumari */ 1101e1e598dSJonathan Doman inline void 1111e1e598dSJonathan Doman modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1121e1e598dSJonathan Doman bool isCpuFunctional) 11357e8c9beSAlpana Kumari { 1141e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional; 11557e8c9beSAlpana Kumari 11602cad96eSEd Tanous const nlohmann::json& prevProcState = 11757e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 11857e8c9beSAlpana Kumari 11957e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 12057e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 12157e8c9beSAlpana Kumari // Functional. 12257e8c9beSAlpana Kumari if (prevProcState == "Disabled") 12357e8c9beSAlpana Kumari { 124e05aec50SEd Tanous if (isCpuFunctional) 12557e8c9beSAlpana Kumari { 12657e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 12757e8c9beSAlpana Kumari "Enabled"; 12857e8c9beSAlpana Kumari } 12957e8c9beSAlpana Kumari } 13057e8c9beSAlpana Kumari } 13157e8c9beSAlpana Kumari 132382d6475SAli Ahmed inline void getProcessorProperties( 133382d6475SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, 134382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 135382d6475SAli Ahmed properties) 13603fbed92SAli Ahmed { 13703fbed92SAli Ahmed 13803fbed92SAli Ahmed BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties."; 13903fbed92SAli Ahmed 14003fbed92SAli Ahmed // TODO: Get Model 14103fbed92SAli Ahmed 142bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 14303fbed92SAli Ahmed 144bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 145bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 14603fbed92SAli Ahmed 147bc1d29deSKrzysztof Grobelny if (!success) 14803fbed92SAli Ahmed { 14903fbed92SAli Ahmed messages::internalError(aResp->res); 15003fbed92SAli Ahmed return; 15103fbed92SAli Ahmed } 15203fbed92SAli Ahmed 153bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 15403fbed92SAli Ahmed { 155bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 156bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 157bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 158bc1d29deSKrzysztof Grobelny 159bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 160bc1d29deSKrzysztof Grobelny { 161bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 16203fbed92SAli Ahmed } 16303fbed92SAli Ahmed else 16403fbed92SAli Ahmed { 165bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 16603fbed92SAli Ahmed } 16703fbed92SAli Ahmed } 16803fbed92SAli Ahmed } 16903fbed92SAli Ahmed 17003fbed92SAli Ahmed /* 17103fbed92SAli Ahmed * @brief Get ProcessorSummary fields 17203fbed92SAli Ahmed * 17303fbed92SAli Ahmed * @param[in] aResp Shared pointer for completing asynchronous calls 17403fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 17503fbed92SAli Ahmed * @param[in] path dbus path for Cpu 17603fbed92SAli Ahmed * 17703fbed92SAli Ahmed * @return None. 17803fbed92SAli Ahmed */ 17903fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 18003fbed92SAli Ahmed const std::string& service, 18103fbed92SAli Ahmed const std::string& path) 18203fbed92SAli Ahmed { 18303fbed92SAli Ahmed 184382d6475SAli Ahmed auto getCpuPresenceState = [aResp](const boost::system::error_code ec3, 185382d6475SAli Ahmed const bool cpuPresenceCheck) { 186382d6475SAli Ahmed if (ec3) 187382d6475SAli Ahmed { 188382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 189382d6475SAli Ahmed return; 190382d6475SAli Ahmed } 191382d6475SAli Ahmed modifyCpuPresenceState(aResp, cpuPresenceCheck); 192382d6475SAli Ahmed }; 193382d6475SAli Ahmed 194382d6475SAli Ahmed auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3, 195382d6475SAli Ahmed const bool cpuFunctionalCheck) { 196382d6475SAli Ahmed if (ec3) 197382d6475SAli Ahmed { 198382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 199382d6475SAli Ahmed return; 200382d6475SAli Ahmed } 201382d6475SAli Ahmed modifyCpuFunctionalState(aResp, cpuFunctionalCheck); 202382d6475SAli Ahmed }; 203382d6475SAli Ahmed 204382d6475SAli Ahmed // Get the Presence of CPU 205382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 206382d6475SAli Ahmed *crow::connections::systemBus, service, path, 207382d6475SAli Ahmed "xyz.openbmc_project.Inventory.Item", "Present", 208382d6475SAli Ahmed std::move(getCpuPresenceState)); 209382d6475SAli Ahmed 210382d6475SAli Ahmed // Get the Functional State 211382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 212382d6475SAli Ahmed *crow::connections::systemBus, service, path, 213382d6475SAli Ahmed "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional", 214382d6475SAli Ahmed std::move(getCpuFunctionalState)); 215382d6475SAli Ahmed 216bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 217bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 218bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 21903fbed92SAli Ahmed [aResp, service, 22003fbed92SAli Ahmed path](const boost::system::error_code ec2, 221b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 22203fbed92SAli Ahmed if (ec2) 22303fbed92SAli Ahmed { 22403fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 22503fbed92SAli Ahmed messages::internalError(aResp->res); 22603fbed92SAli Ahmed return; 22703fbed92SAli Ahmed } 228382d6475SAli Ahmed getProcessorProperties(aResp, properties); 229bc1d29deSKrzysztof Grobelny }); 23003fbed92SAli Ahmed } 23103fbed92SAli Ahmed 23257e8c9beSAlpana Kumari /* 233c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 234c5b2abe0SLewanczyk, Dawid * 235c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 2368f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 237c5b2abe0SLewanczyk, Dawid * 238c5b2abe0SLewanczyk, Dawid * @return None. 239c5b2abe0SLewanczyk, Dawid */ 240b5a76932SEd Tanous inline void 2418d1b46d7Szhanghch05 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 242b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 2431abe55efSEd Tanous { 24455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 245e99073f5SGeorge Liu constexpr std::array<std::string_view, 5> interfaces = { 246e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Asset", 247e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cpu", 248e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm", 249e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System", 250e99073f5SGeorge Liu "xyz.openbmc_project.Common.UUID", 251e99073f5SGeorge Liu }; 252e99073f5SGeorge Liu dbus::utility::getSubTree( 253e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 254b9d36b47SEd Tanous [aResp, 255e99073f5SGeorge Liu systemHealth](const boost::system::error_code& ec, 256b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 2571abe55efSEd Tanous if (ec) 2581abe55efSEd Tanous { 25955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 260f12894f8SJason M. Bills messages::internalError(aResp->res); 261c5b2abe0SLewanczyk, Dawid return; 262c5b2abe0SLewanczyk, Dawid } 263c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 264002d39b4SEd Tanous for (const std::pair< 265002d39b4SEd Tanous std::string, 266002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 2671214b7e7SGunnar Mills object : subtree) 2681abe55efSEd Tanous { 269c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 27055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 271002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 2721214b7e7SGunnar Mills connectionNames = object.second; 27326f6976fSEd Tanous if (connectionNames.empty()) 2741abe55efSEd Tanous { 275c5b2abe0SLewanczyk, Dawid continue; 276c5b2abe0SLewanczyk, Dawid } 277029573d4SEd Tanous 2785bc2dc8eSJames Feist auto memoryHealth = std::make_shared<HealthPopulate>( 279dfababfcSNan Zhou aResp, "/MemorySummary/Status"_json_pointer); 2805bc2dc8eSJames Feist 2815bc2dc8eSJames Feist auto cpuHealth = std::make_shared<HealthPopulate>( 282dfababfcSNan Zhou aResp, "/ProcessorSummary/Status"_json_pointer); 2835bc2dc8eSJames Feist 2845bc2dc8eSJames Feist systemHealth->children.emplace_back(memoryHealth); 2855bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 2865bc2dc8eSJames Feist 2876c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 2886c34de48SEd Tanous // BiosVer 28904a258f4SEd Tanous for (const auto& connection : connectionNames) 2901abe55efSEd Tanous { 29104a258f4SEd Tanous for (const auto& interfaceName : connection.second) 2921abe55efSEd Tanous { 29304a258f4SEd Tanous if (interfaceName == 29404a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 2951abe55efSEd Tanous { 2961abe55efSEd Tanous BMCWEB_LOG_DEBUG 29704a258f4SEd Tanous << "Found Dimm, now get its properties."; 2989d3ae10eSAlpana Kumari 299bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 300bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 301bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Inventory.Item.Dimm", 3029d3ae10eSAlpana Kumari [aResp, service{connection.first}, 303f23b7296SEd Tanous path](const boost::system::error_code ec2, 304b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 3051214b7e7SGunnar Mills properties) { 306cb13a392SEd Tanous if (ec2) 3071abe55efSEd Tanous { 308002d39b4SEd Tanous BMCWEB_LOG_ERROR << "DBUS response error " 309002d39b4SEd Tanous << ec2; 310f12894f8SJason M. Bills messages::internalError(aResp->res); 311c5b2abe0SLewanczyk, Dawid return; 312c5b2abe0SLewanczyk, Dawid } 313002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 314c5b2abe0SLewanczyk, Dawid << " Dimm properties."; 3159d3ae10eSAlpana Kumari 316bc1d29deSKrzysztof Grobelny if (properties.empty()) 3179d3ae10eSAlpana Kumari { 3181e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 319002d39b4SEd Tanous *crow::connections::systemBus, service, 320002d39b4SEd Tanous path, 3211e1e598dSJonathan Doman "xyz.openbmc_project.State." 3221e1e598dSJonathan Doman "Decorator.OperationalStatus", 3231e1e598dSJonathan Doman "Functional", 324002d39b4SEd Tanous [aResp](const boost::system::error_code ec3, 3251e1e598dSJonathan Doman bool dimmState) { 326cb13a392SEd Tanous if (ec3) 3279d3ae10eSAlpana Kumari { 3289d3ae10eSAlpana Kumari BMCWEB_LOG_ERROR 329002d39b4SEd Tanous << "DBUS response error " << ec3; 3309d3ae10eSAlpana Kumari return; 3319d3ae10eSAlpana Kumari } 332002d39b4SEd Tanous updateDimmProperties(aResp, dimmState); 3331e1e598dSJonathan Doman }); 334bc1d29deSKrzysztof Grobelny return; 3359d3ae10eSAlpana Kumari } 336bc1d29deSKrzysztof Grobelny 337bc1d29deSKrzysztof Grobelny const uint32_t* memorySizeInKB = nullptr; 338bc1d29deSKrzysztof Grobelny 339bc1d29deSKrzysztof Grobelny const bool success = 340bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 341bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 342bc1d29deSKrzysztof Grobelny properties, "MemorySizeInKB", 343bc1d29deSKrzysztof Grobelny memorySizeInKB); 344bc1d29deSKrzysztof Grobelny 345bc1d29deSKrzysztof Grobelny if (!success) 346bc1d29deSKrzysztof Grobelny { 347bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 348bc1d29deSKrzysztof Grobelny return; 349bc1d29deSKrzysztof Grobelny } 350bc1d29deSKrzysztof Grobelny 351bc1d29deSKrzysztof Grobelny if (memorySizeInKB != nullptr) 352bc1d29deSKrzysztof Grobelny { 353bc1d29deSKrzysztof Grobelny nlohmann::json& totalMemory = 354bc1d29deSKrzysztof Grobelny aResp->res 355bc1d29deSKrzysztof Grobelny .jsonValue["MemorySummary"] 356bc1d29deSKrzysztof Grobelny ["TotalSystemMemoryGiB"]; 357bc1d29deSKrzysztof Grobelny const uint64_t* preValue = 358bc1d29deSKrzysztof Grobelny totalMemory.get_ptr<const uint64_t*>(); 359bc1d29deSKrzysztof Grobelny if (preValue == nullptr) 360bc1d29deSKrzysztof Grobelny { 361bc1d29deSKrzysztof Grobelny aResp->res 362bc1d29deSKrzysztof Grobelny .jsonValue["MemorySummary"] 363bc1d29deSKrzysztof Grobelny ["TotalSystemMemoryGiB"] = 364bc1d29deSKrzysztof Grobelny *memorySizeInKB / (1024 * 1024); 365bc1d29deSKrzysztof Grobelny } 366bc1d29deSKrzysztof Grobelny else 367bc1d29deSKrzysztof Grobelny { 368bc1d29deSKrzysztof Grobelny aResp->res 369bc1d29deSKrzysztof Grobelny .jsonValue["MemorySummary"] 370bc1d29deSKrzysztof Grobelny ["TotalSystemMemoryGiB"] = 371bc1d29deSKrzysztof Grobelny *memorySizeInKB / (1024 * 1024) + 372bc1d29deSKrzysztof Grobelny *preValue; 373bc1d29deSKrzysztof Grobelny } 374bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["MemorySummary"]["Status"] 375bc1d29deSKrzysztof Grobelny ["State"] = "Enabled"; 376bc1d29deSKrzysztof Grobelny } 377bc1d29deSKrzysztof Grobelny }); 3785bc2dc8eSJames Feist 3795bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 3801abe55efSEd Tanous } 38104a258f4SEd Tanous else if (interfaceName == 38204a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 3831abe55efSEd Tanous { 3841abe55efSEd Tanous BMCWEB_LOG_DEBUG 38504a258f4SEd Tanous << "Found Cpu, now get its properties."; 38657e8c9beSAlpana Kumari 38703fbed92SAli Ahmed getProcessorSummary(aResp, connection.first, path); 3885bc2dc8eSJames Feist 3895bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 3901abe55efSEd Tanous } 391002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 3921abe55efSEd Tanous { 3931abe55efSEd Tanous BMCWEB_LOG_DEBUG 39404a258f4SEd Tanous << "Found UUID, now get its properties."; 395bc1d29deSKrzysztof Grobelny 396bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 397bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 398bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Common.UUID", 399168e20c1SEd Tanous [aResp](const boost::system::error_code ec3, 400b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4011214b7e7SGunnar Mills properties) { 402cb13a392SEd Tanous if (ec3) 4031abe55efSEd Tanous { 404002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " 405002d39b4SEd Tanous << ec3; 406f12894f8SJason M. Bills messages::internalError(aResp->res); 407c5b2abe0SLewanczyk, Dawid return; 408c5b2abe0SLewanczyk, Dawid } 409002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 410c5b2abe0SLewanczyk, Dawid << " UUID properties."; 41104a258f4SEd Tanous 412bc1d29deSKrzysztof Grobelny const std::string* uUID = nullptr; 413bc1d29deSKrzysztof Grobelny 414bc1d29deSKrzysztof Grobelny const bool success = 415bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 416bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 417bc1d29deSKrzysztof Grobelny properties, "UUID", uUID); 418bc1d29deSKrzysztof Grobelny 419bc1d29deSKrzysztof Grobelny if (!success) 4201abe55efSEd Tanous { 421bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 422bc1d29deSKrzysztof Grobelny return; 423bc1d29deSKrzysztof Grobelny } 424bc1d29deSKrzysztof Grobelny 425bc1d29deSKrzysztof Grobelny if (uUID != nullptr) 426bc1d29deSKrzysztof Grobelny { 427bc1d29deSKrzysztof Grobelny std::string valueStr = *uUID; 42804a258f4SEd Tanous if (valueStr.size() == 32) 4291abe55efSEd Tanous { 430029573d4SEd Tanous valueStr.insert(8, 1, '-'); 431029573d4SEd Tanous valueStr.insert(13, 1, '-'); 432029573d4SEd Tanous valueStr.insert(18, 1, '-'); 433029573d4SEd Tanous valueStr.insert(23, 1, '-'); 43404a258f4SEd Tanous } 435bc1d29deSKrzysztof Grobelny BMCWEB_LOG_DEBUG << "UUID = " << valueStr; 436002d39b4SEd Tanous aResp->res.jsonValue["UUID"] = valueStr; 437c5b2abe0SLewanczyk, Dawid } 438bc1d29deSKrzysztof Grobelny }); 439c5b2abe0SLewanczyk, Dawid } 440029573d4SEd Tanous else if (interfaceName == 441029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4421abe55efSEd Tanous { 443bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 444bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 445bc1d29deSKrzysztof Grobelny path, 446bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 447168e20c1SEd Tanous [aResp](const boost::system::error_code ec2, 448b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4491214b7e7SGunnar Mills propertiesList) { 450cb13a392SEd Tanous if (ec2) 451029573d4SEd Tanous { 452e4a4b9a9SJames Feist // doesn't have to include this 453e4a4b9a9SJames Feist // interface 454029573d4SEd Tanous return; 455029573d4SEd Tanous } 456002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 457029573d4SEd Tanous << " properties for system"; 458bc1d29deSKrzysztof Grobelny 459bc1d29deSKrzysztof Grobelny const std::string* partNumber = nullptr; 460bc1d29deSKrzysztof Grobelny const std::string* serialNumber = nullptr; 461bc1d29deSKrzysztof Grobelny const std::string* manufacturer = nullptr; 462bc1d29deSKrzysztof Grobelny const std::string* model = nullptr; 463bc1d29deSKrzysztof Grobelny const std::string* subModel = nullptr; 464bc1d29deSKrzysztof Grobelny 465bc1d29deSKrzysztof Grobelny const bool success = 466bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 467bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 468bc1d29deSKrzysztof Grobelny propertiesList, "PartNumber", partNumber, 469bc1d29deSKrzysztof Grobelny "SerialNumber", serialNumber, 470bc1d29deSKrzysztof Grobelny "Manufacturer", manufacturer, "Model", 471bc1d29deSKrzysztof Grobelny model, "SubModel", subModel); 472bc1d29deSKrzysztof Grobelny 473bc1d29deSKrzysztof Grobelny if (!success) 474029573d4SEd Tanous { 475bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 476bc1d29deSKrzysztof Grobelny return; 477029573d4SEd Tanous } 478bc1d29deSKrzysztof Grobelny 479bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 480bc1d29deSKrzysztof Grobelny { 481bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["PartNumber"] = 482bc1d29deSKrzysztof Grobelny *partNumber; 483029573d4SEd Tanous } 484bc1d29deSKrzysztof Grobelny 485bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 486bc1d29deSKrzysztof Grobelny { 487bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SerialNumber"] = 488bc1d29deSKrzysztof Grobelny *serialNumber; 489bc1d29deSKrzysztof Grobelny } 490bc1d29deSKrzysztof Grobelny 491bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 492bc1d29deSKrzysztof Grobelny { 493bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Manufacturer"] = 494bc1d29deSKrzysztof Grobelny *manufacturer; 495bc1d29deSKrzysztof Grobelny } 496bc1d29deSKrzysztof Grobelny 497bc1d29deSKrzysztof Grobelny if (model != nullptr) 498bc1d29deSKrzysztof Grobelny { 499bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Model"] = *model; 500bc1d29deSKrzysztof Grobelny } 501bc1d29deSKrzysztof Grobelny 502bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 503bc1d29deSKrzysztof Grobelny { 504bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SubModel"] = *subModel; 505fc5afcf9Sbeccabroek } 506c1e236a6SGunnar Mills 507cb7e1e7bSAndrew Geissler // Grab the bios version 508eee0013eSWilly Tu sw_util::populateSoftwareInformation( 509eee0013eSWilly Tu aResp, sw_util::biosPurpose, "BiosVersion", 510002d39b4SEd Tanous false); 511bc1d29deSKrzysztof Grobelny }); 512e4a4b9a9SJames Feist 5131e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5141e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5151e1e598dSJonathan Doman path, 5161e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5171e1e598dSJonathan Doman "AssetTag", 5181e1e598dSJonathan Doman "AssetTag", 519168e20c1SEd Tanous [aResp](const boost::system::error_code ec2, 5201e1e598dSJonathan Doman const std::string& value) { 521cb13a392SEd Tanous if (ec2) 522e4a4b9a9SJames Feist { 523e4a4b9a9SJames Feist // doesn't have to include this 524e4a4b9a9SJames Feist // interface 525e4a4b9a9SJames Feist return; 526e4a4b9a9SJames Feist } 527e4a4b9a9SJames Feist 5281e1e598dSJonathan Doman aResp->res.jsonValue["AssetTag"] = value; 5291e1e598dSJonathan Doman }); 530029573d4SEd Tanous } 531029573d4SEd Tanous } 532bc1d29deSKrzysztof Grobelny break; 533029573d4SEd Tanous } 534c5b2abe0SLewanczyk, Dawid } 5356617338dSEd Tanous }); 536c5b2abe0SLewanczyk, Dawid } 537c5b2abe0SLewanczyk, Dawid 538c5b2abe0SLewanczyk, Dawid /** 539c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 540c5b2abe0SLewanczyk, Dawid * 541c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 542c5b2abe0SLewanczyk, Dawid * 543c5b2abe0SLewanczyk, Dawid * @return None. 544c5b2abe0SLewanczyk, Dawid */ 5458d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 5461abe55efSEd Tanous { 54755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 5481e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5491e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 5501e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 5511e1e598dSJonathan Doman "CurrentHostState", 552c5d03ff4SJennifer Lee [aResp](const boost::system::error_code ec, 5531e1e598dSJonathan Doman const std::string& hostState) { 5541abe55efSEd Tanous if (ec) 5551abe55efSEd Tanous { 55622228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 55722228c28SAndrew Geissler { 55822228c28SAndrew Geissler // Service not available, no error, just don't return 55922228c28SAndrew Geissler // host state info 56022228c28SAndrew Geissler BMCWEB_LOG_DEBUG << "Service not available " << ec; 56122228c28SAndrew Geissler return; 56222228c28SAndrew Geissler } 56322228c28SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 564f12894f8SJason M. Bills messages::internalError(aResp->res); 565c5b2abe0SLewanczyk, Dawid return; 566c5b2abe0SLewanczyk, Dawid } 5676617338dSEd Tanous 5681e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Host state: " << hostState; 569c5b2abe0SLewanczyk, Dawid // Verify Host State 5701e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5711abe55efSEd Tanous { 57255c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 5736617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 5741abe55efSEd Tanous } 5751e1e598dSJonathan Doman else if (hostState == 5760fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5778c888608SGunnar Mills { 5788c888608SGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 5798c888608SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Quiesced"; 5808c888608SGunnar Mills } 5811e1e598dSJonathan Doman else if (hostState == 5820fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 58383935af9SAndrew Geissler { 58483935af9SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 58583935af9SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "InTest"; 58683935af9SAndrew Geissler } 5870fda0f12SGeorge Liu else if ( 5881e1e598dSJonathan Doman hostState == 5890fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5901a2a1437SAndrew Geissler { 5911a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOn"; 59215c27bf8SNoah Brewer aResp->res.jsonValue["Status"]["State"] = "Starting"; 5931a2a1437SAndrew Geissler } 594002d39b4SEd Tanous else if (hostState == 5950fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5961a2a1437SAndrew Geissler { 5971a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOff"; 5981a2a1437SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Disabled"; 5991a2a1437SAndrew Geissler } 6001abe55efSEd Tanous else 6011abe55efSEd Tanous { 60255c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 6036617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 604c5b2abe0SLewanczyk, Dawid } 6051e1e598dSJonathan Doman }); 606c5b2abe0SLewanczyk, Dawid } 607c5b2abe0SLewanczyk, Dawid 608c5b2abe0SLewanczyk, Dawid /** 609786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 610491d8ee7SSantosh Puranik * 611491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 612491d8ee7SSantosh Puranik * 613491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 614491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 615491d8ee7SSantosh Puranik */ 61623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 617491d8ee7SSantosh Puranik { 618491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 619491d8ee7SSantosh Puranik { 620491d8ee7SSantosh Puranik return "None"; 621491d8ee7SSantosh Puranik } 6223174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 623491d8ee7SSantosh Puranik { 624491d8ee7SSantosh Puranik return "Hdd"; 625491d8ee7SSantosh Puranik } 6263174e4dfSEd Tanous if (dbusSource == 627a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 628491d8ee7SSantosh Puranik { 629491d8ee7SSantosh Puranik return "Cd"; 630491d8ee7SSantosh Puranik } 6313174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 632491d8ee7SSantosh Puranik { 633491d8ee7SSantosh Puranik return "Pxe"; 634491d8ee7SSantosh Puranik } 6353174e4dfSEd Tanous if (dbusSource == 636944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6379f16b2c1SJennifer Lee { 6389f16b2c1SJennifer Lee return "Usb"; 6399f16b2c1SJennifer Lee } 640491d8ee7SSantosh Puranik return ""; 641491d8ee7SSantosh Puranik } 642491d8ee7SSantosh Puranik 643491d8ee7SSantosh Puranik /** 644cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 645cd9a4666SKonstantin Aladyshev * 646cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 647cd9a4666SKonstantin Aladyshev * 648cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 649cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 650cd9a4666SKonstantin Aladyshev */ 651cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 652cd9a4666SKonstantin Aladyshev { 653cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 654cd9a4666SKonstantin Aladyshev { 655cd9a4666SKonstantin Aladyshev return "Legacy"; 656cd9a4666SKonstantin Aladyshev } 657cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 658cd9a4666SKonstantin Aladyshev { 659cd9a4666SKonstantin Aladyshev return "UEFI"; 660cd9a4666SKonstantin Aladyshev } 661cd9a4666SKonstantin Aladyshev return ""; 662cd9a4666SKonstantin Aladyshev } 663cd9a4666SKonstantin Aladyshev 664cd9a4666SKonstantin Aladyshev /** 665786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 666491d8ee7SSantosh Puranik * 667491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 668491d8ee7SSantosh Puranik * 669491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 670491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 671491d8ee7SSantosh Puranik */ 67223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 673491d8ee7SSantosh Puranik { 674491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 675491d8ee7SSantosh Puranik { 676491d8ee7SSantosh Puranik return "None"; 677491d8ee7SSantosh Puranik } 6783174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 679491d8ee7SSantosh Puranik { 680491d8ee7SSantosh Puranik return "Diags"; 681491d8ee7SSantosh Puranik } 6823174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 683491d8ee7SSantosh Puranik { 684491d8ee7SSantosh Puranik return "BiosSetup"; 685491d8ee7SSantosh Puranik } 686491d8ee7SSantosh Puranik return ""; 687491d8ee7SSantosh Puranik } 688491d8ee7SSantosh Puranik 689491d8ee7SSantosh Puranik /** 690e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 691e43914b3SAndrew Geissler * 692e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 693e43914b3SAndrew Geissler * 694e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 695e43914b3SAndrew Geissler * translation cannot be done, returns "None". 696e43914b3SAndrew Geissler */ 697e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 698e43914b3SAndrew Geissler { 699e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 700e43914b3SAndrew Geissler // enum 701e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 702e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 703e43914b3SAndrew Geissler "ProgressStages.Unspecified") 704e43914b3SAndrew Geissler { 705e43914b3SAndrew Geissler rfBpLastState = "None"; 706e43914b3SAndrew Geissler } 707e43914b3SAndrew Geissler else if (dbusBootProgress == 708e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 709e43914b3SAndrew Geissler "PrimaryProcInit") 710e43914b3SAndrew Geissler { 711e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 712e43914b3SAndrew Geissler } 713e43914b3SAndrew Geissler else if (dbusBootProgress == 714e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 715e43914b3SAndrew Geissler "BusInit") 716e43914b3SAndrew Geissler { 717e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 718e43914b3SAndrew Geissler } 719e43914b3SAndrew Geissler else if (dbusBootProgress == 720e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 721e43914b3SAndrew Geissler "MemoryInit") 722e43914b3SAndrew Geissler { 723e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 724e43914b3SAndrew Geissler } 725e43914b3SAndrew Geissler else if (dbusBootProgress == 726e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 727e43914b3SAndrew Geissler "SecondaryProcInit") 728e43914b3SAndrew Geissler { 729e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 730e43914b3SAndrew Geissler } 731e43914b3SAndrew Geissler else if (dbusBootProgress == 732e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 733e43914b3SAndrew Geissler "PCIInit") 734e43914b3SAndrew Geissler { 735e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 736e43914b3SAndrew Geissler } 737e43914b3SAndrew Geissler else if (dbusBootProgress == 738e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 739e43914b3SAndrew Geissler "SystemSetup") 740e43914b3SAndrew Geissler { 741e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 742e43914b3SAndrew Geissler } 743e43914b3SAndrew Geissler else if (dbusBootProgress == 744e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 745e43914b3SAndrew Geissler "SystemInitComplete") 746e43914b3SAndrew Geissler { 747e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 748e43914b3SAndrew Geissler } 749e43914b3SAndrew Geissler else if (dbusBootProgress == 750e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 751e43914b3SAndrew Geissler "OSStart") 752e43914b3SAndrew Geissler { 753e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 754e43914b3SAndrew Geissler } 755e43914b3SAndrew Geissler else if (dbusBootProgress == 756e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 757e43914b3SAndrew Geissler "OSRunning") 758e43914b3SAndrew Geissler { 759e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 760e43914b3SAndrew Geissler } 761e43914b3SAndrew Geissler else 762e43914b3SAndrew Geissler { 763e43914b3SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 764e43914b3SAndrew Geissler << dbusBootProgress; 765e43914b3SAndrew Geissler // Just return the default 766e43914b3SAndrew Geissler } 767e43914b3SAndrew Geissler return rfBpLastState; 768e43914b3SAndrew Geissler } 769e43914b3SAndrew Geissler 770e43914b3SAndrew Geissler /** 771786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 772491d8ee7SSantosh Puranik * 773491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 774944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 775944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 776491d8ee7SSantosh Puranik * 777944ffaf9SJohnathan Mantey * @return Integer error code. 778491d8ee7SSantosh Puranik */ 7798d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 780944ffaf9SJohnathan Mantey const std::string& rfSource, 781944ffaf9SJohnathan Mantey std::string& bootSource, std::string& bootMode) 782491d8ee7SSantosh Puranik { 783c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 784c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 785944ffaf9SJohnathan Mantey 786491d8ee7SSantosh Puranik if (rfSource == "None") 787491d8ee7SSantosh Puranik { 788944ffaf9SJohnathan Mantey return 0; 789491d8ee7SSantosh Puranik } 7903174e4dfSEd Tanous if (rfSource == "Pxe") 791491d8ee7SSantosh Puranik { 792944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 793944ffaf9SJohnathan Mantey } 794944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 795944ffaf9SJohnathan Mantey { 796944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 797944ffaf9SJohnathan Mantey } 798944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 799944ffaf9SJohnathan Mantey { 800944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 801944ffaf9SJohnathan Mantey } 802944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 803944ffaf9SJohnathan Mantey { 804944ffaf9SJohnathan Mantey bootSource = 805944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 806944ffaf9SJohnathan Mantey } 807944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 808944ffaf9SJohnathan Mantey { 809944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 810491d8ee7SSantosh Puranik } 8119f16b2c1SJennifer Lee else if (rfSource == "Usb") 8129f16b2c1SJennifer Lee { 813944ffaf9SJohnathan Mantey bootSource = 814944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8159f16b2c1SJennifer Lee } 816491d8ee7SSantosh Puranik else 817491d8ee7SSantosh Puranik { 8180fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 8190fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideTarget: " 820944ffaf9SJohnathan Mantey << bootSource; 821944ffaf9SJohnathan Mantey messages::propertyValueNotInList(aResp->res, rfSource, 822944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 823944ffaf9SJohnathan Mantey return -1; 824491d8ee7SSantosh Puranik } 825944ffaf9SJohnathan Mantey return 0; 826491d8ee7SSantosh Puranik } 8271981771bSAli Ahmed 828978b8803SAndrew Geissler /** 829978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 830978b8803SAndrew Geissler * 831978b8803SAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 832978b8803SAndrew Geissler * 833978b8803SAndrew Geissler * @return None. 834978b8803SAndrew Geissler */ 8358d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 836978b8803SAndrew Geissler { 8371e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8381e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8391e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8401e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 841978b8803SAndrew Geissler [aResp](const boost::system::error_code ec, 8421e1e598dSJonathan Doman const std::string& bootProgressStr) { 843978b8803SAndrew Geissler if (ec) 844978b8803SAndrew Geissler { 845978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 846978b8803SAndrew Geissler // not found 847978b8803SAndrew Geissler return; 848978b8803SAndrew Geissler } 849978b8803SAndrew Geissler 8501e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr; 851978b8803SAndrew Geissler 852e43914b3SAndrew Geissler aResp->res.jsonValue["BootProgress"]["LastState"] = 853e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8541e1e598dSJonathan Doman }); 855978b8803SAndrew Geissler } 856491d8ee7SSantosh Puranik 857491d8ee7SSantosh Puranik /** 858b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 859b6d5d45cSHieu Huynh * 860b6d5d45cSHieu Huynh * @param[in] aResp Shared pointer for generating response message. 861b6d5d45cSHieu Huynh * 862b6d5d45cSHieu Huynh * @return None. 863b6d5d45cSHieu Huynh */ 864b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 865b6d5d45cSHieu Huynh const std::shared_ptr<bmcweb::AsyncResp>& aResp) 866b6d5d45cSHieu Huynh { 867b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 868b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 869b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 870b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 871b6d5d45cSHieu Huynh [aResp](const boost::system::error_code ec, 872b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 873b6d5d45cSHieu Huynh if (ec) 874b6d5d45cSHieu Huynh { 875b6d5d45cSHieu Huynh BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 876b6d5d45cSHieu Huynh return; 877b6d5d45cSHieu Huynh } 878b6d5d45cSHieu Huynh 879b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 880b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 881b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 882b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 883b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 884b6d5d45cSHieu Huynh 885b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 886b6d5d45cSHieu Huynh aResp->res.jsonValue["BootProgress"]["LastStateTime"] = 887b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 888b6d5d45cSHieu Huynh }); 889b6d5d45cSHieu Huynh } 890b6d5d45cSHieu Huynh 891b6d5d45cSHieu Huynh /** 892c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 893cd9a4666SKonstantin Aladyshev * 894cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 895cd9a4666SKonstantin Aladyshev * 896cd9a4666SKonstantin Aladyshev * @return None. 897cd9a4666SKonstantin Aladyshev */ 898cd9a4666SKonstantin Aladyshev 899c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 900cd9a4666SKonstantin Aladyshev { 9011e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9021e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9031e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9041e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 905cd9a4666SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 9061e1e598dSJonathan Doman const std::string& bootType) { 907cd9a4666SKonstantin Aladyshev if (ec) 908cd9a4666SKonstantin Aladyshev { 909cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 910cd9a4666SKonstantin Aladyshev return; 911cd9a4666SKonstantin Aladyshev } 912cd9a4666SKonstantin Aladyshev 9131e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot type: " << bootType; 914cd9a4666SKonstantin Aladyshev 915002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 916002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 917613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 918cd9a4666SKonstantin Aladyshev 9191e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 920cd9a4666SKonstantin Aladyshev if (rfType.empty()) 921cd9a4666SKonstantin Aladyshev { 922cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 923cd9a4666SKonstantin Aladyshev return; 924cd9a4666SKonstantin Aladyshev } 925cd9a4666SKonstantin Aladyshev 926cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9271e1e598dSJonathan Doman }); 928cd9a4666SKonstantin Aladyshev } 929cd9a4666SKonstantin Aladyshev 930cd9a4666SKonstantin Aladyshev /** 931c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 932491d8ee7SSantosh Puranik * 933491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 934491d8ee7SSantosh Puranik * 935491d8ee7SSantosh Puranik * @return None. 936491d8ee7SSantosh Puranik */ 937c21865c4SKonstantin Aladyshev 938c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 939491d8ee7SSantosh Puranik { 9401e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9411e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9421e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9431e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 944c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 9451e1e598dSJonathan Doman const std::string& bootModeStr) { 946491d8ee7SSantosh Puranik if (ec) 947491d8ee7SSantosh Puranik { 948491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 949491d8ee7SSantosh Puranik messages::internalError(aResp->res); 950491d8ee7SSantosh Puranik return; 951491d8ee7SSantosh Puranik } 952491d8ee7SSantosh Puranik 9531e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 954491d8ee7SSantosh Puranik 9550fda0f12SGeorge Liu aResp->res 9560fda0f12SGeorge Liu .jsonValue["Boot"] 957002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 958002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 959491d8ee7SSantosh Puranik 9601e1e598dSJonathan Doman if (bootModeStr != 961491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 962491d8ee7SSantosh Puranik { 9631e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 964491d8ee7SSantosh Puranik if (!rfMode.empty()) 965491d8ee7SSantosh Puranik { 966491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 967491d8ee7SSantosh Puranik rfMode; 968491d8ee7SSantosh Puranik } 969491d8ee7SSantosh Puranik } 9701e1e598dSJonathan Doman }); 971491d8ee7SSantosh Puranik } 972491d8ee7SSantosh Puranik 973491d8ee7SSantosh Puranik /** 974c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 975491d8ee7SSantosh Puranik * 976491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 977491d8ee7SSantosh Puranik * 978491d8ee7SSantosh Puranik * @return None. 979491d8ee7SSantosh Puranik */ 980c21865c4SKonstantin Aladyshev 981c21865c4SKonstantin Aladyshev inline void 982c21865c4SKonstantin Aladyshev getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 983491d8ee7SSantosh Puranik { 9841e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9851e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9861e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9871e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 988c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 9891e1e598dSJonathan Doman const std::string& bootSourceStr) { 990491d8ee7SSantosh Puranik if (ec) 991491d8ee7SSantosh Puranik { 992491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 9935ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 9945ef735c8SNan Zhou { 9955ef735c8SNan Zhou return; 9965ef735c8SNan Zhou } 997491d8ee7SSantosh Puranik messages::internalError(aResp->res); 998491d8ee7SSantosh Puranik return; 999491d8ee7SSantosh Puranik } 1000491d8ee7SSantosh Puranik 10011e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr; 1002491d8ee7SSantosh Puranik 10031e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1004491d8ee7SSantosh Puranik if (!rfSource.empty()) 1005491d8ee7SSantosh Puranik { 1006002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource; 1007491d8ee7SSantosh Puranik } 1008cd9a4666SKonstantin Aladyshev 1009cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1010cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1011c21865c4SKonstantin Aladyshev getBootOverrideMode(aResp); 10121e1e598dSJonathan Doman }); 1013491d8ee7SSantosh Puranik } 1014491d8ee7SSantosh Puranik 1015491d8ee7SSantosh Puranik /** 1016c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1017c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1018c21865c4SKonstantin Aladyshev * state 1019491d8ee7SSantosh Puranik * 1020491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1021491d8ee7SSantosh Puranik * 1022491d8ee7SSantosh Puranik * @return None. 1023491d8ee7SSantosh Puranik */ 1024491d8ee7SSantosh Puranik 1025c21865c4SKonstantin Aladyshev inline void 1026c21865c4SKonstantin Aladyshev processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1027c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1028c21865c4SKonstantin Aladyshev { 1029c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1030c21865c4SKonstantin Aladyshev { 1031c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; 1032c21865c4SKonstantin Aladyshev return; 1033c21865c4SKonstantin Aladyshev } 1034c21865c4SKonstantin Aladyshev 1035c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1036c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10371e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10381e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10391e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10401e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 10411e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, bool oneTimeSetting) { 1042491d8ee7SSantosh Puranik if (ec) 1043491d8ee7SSantosh Puranik { 1044491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1045c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1046491d8ee7SSantosh Puranik return; 1047491d8ee7SSantosh Puranik } 1048491d8ee7SSantosh Puranik 1049c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1050c21865c4SKonstantin Aladyshev { 1051002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once"; 1052c21865c4SKonstantin Aladyshev } 1053c21865c4SKonstantin Aladyshev else 1054c21865c4SKonstantin Aladyshev { 1055c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1056c21865c4SKonstantin Aladyshev "Continuous"; 1057c21865c4SKonstantin Aladyshev } 10581e1e598dSJonathan Doman }); 1059491d8ee7SSantosh Puranik } 1060491d8ee7SSantosh Puranik 1061491d8ee7SSantosh Puranik /** 1062c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1063c21865c4SKonstantin Aladyshev * 1064c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1065c21865c4SKonstantin Aladyshev * 1066c21865c4SKonstantin Aladyshev * @return None. 1067c21865c4SKonstantin Aladyshev */ 1068c21865c4SKonstantin Aladyshev 1069c21865c4SKonstantin Aladyshev inline void 1070c21865c4SKonstantin Aladyshev getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1071c21865c4SKonstantin Aladyshev { 10721e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10731e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10741e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10751e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1076c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 10771e1e598dSJonathan Doman const bool bootOverrideEnable) { 1078c21865c4SKonstantin Aladyshev if (ec) 1079c21865c4SKonstantin Aladyshev { 1080c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 10815ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10825ef735c8SNan Zhou { 10835ef735c8SNan Zhou return; 10845ef735c8SNan Zhou } 1085c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1086c21865c4SKonstantin Aladyshev return; 1087c21865c4SKonstantin Aladyshev } 1088c21865c4SKonstantin Aladyshev 10891e1e598dSJonathan Doman processBootOverrideEnable(aResp, bootOverrideEnable); 10901e1e598dSJonathan Doman }); 1091c21865c4SKonstantin Aladyshev } 1092c21865c4SKonstantin Aladyshev 1093c21865c4SKonstantin Aladyshev /** 1094c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1095c21865c4SKonstantin Aladyshev * 1096c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1097c21865c4SKonstantin Aladyshev * 1098c21865c4SKonstantin Aladyshev * @return None. 1099c21865c4SKonstantin Aladyshev */ 1100c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1101c21865c4SKonstantin Aladyshev { 1102c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1103c21865c4SKonstantin Aladyshev 1104c21865c4SKonstantin Aladyshev getBootOverrideSource(aResp); 1105c21865c4SKonstantin Aladyshev getBootOverrideType(aResp); 1106c21865c4SKonstantin Aladyshev getBootOverrideEnable(aResp); 1107c21865c4SKonstantin Aladyshev } 1108c21865c4SKonstantin Aladyshev 1109c21865c4SKonstantin Aladyshev /** 1110c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1111c0557e1aSGunnar Mills * 1112c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1113c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1114c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1115c0557e1aSGunnar Mills * last power operation time. 1116c0557e1aSGunnar Mills * 1117c0557e1aSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 1118c0557e1aSGunnar Mills * 1119c0557e1aSGunnar Mills * @return None. 1120c0557e1aSGunnar Mills */ 11218d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1122c0557e1aSGunnar Mills { 1123c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1124c0557e1aSGunnar Mills 11251e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11261e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11271e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11281e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 11291e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, uint64_t lastResetTime) { 1130c0557e1aSGunnar Mills if (ec) 1131c0557e1aSGunnar Mills { 1132c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1133c0557e1aSGunnar Mills return; 1134c0557e1aSGunnar Mills } 1135c0557e1aSGunnar Mills 1136c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1137c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11381e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1139c0557e1aSGunnar Mills 1140c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1141c0557e1aSGunnar Mills aResp->res.jsonValue["LastResetTime"] = 11422b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11431e1e598dSJonathan Doman }); 1144c0557e1aSGunnar Mills } 1145c0557e1aSGunnar Mills 1146c0557e1aSGunnar Mills /** 11476bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 11486bd5a8d2SGunnar Mills * 11496bd5a8d2SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 11506bd5a8d2SGunnar Mills * 11516bd5a8d2SGunnar Mills * @return None. 11526bd5a8d2SGunnar Mills */ 11538d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 11546bd5a8d2SGunnar Mills { 11556bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 11566bd5a8d2SGunnar Mills 11571e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11581e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11591e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 11601e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 11611e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, bool autoRebootEnabled) { 11626bd5a8d2SGunnar Mills if (ec) 11636bd5a8d2SGunnar Mills { 11646bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 11656bd5a8d2SGunnar Mills return; 11666bd5a8d2SGunnar Mills } 11676bd5a8d2SGunnar Mills 11681e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled; 1169e05aec50SEd Tanous if (autoRebootEnabled) 11706bd5a8d2SGunnar Mills { 11716bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 11726bd5a8d2SGunnar Mills "RetryAttempts"; 11736bd5a8d2SGunnar Mills // If AutomaticRetry (AutoReboot) is enabled see how many 11746bd5a8d2SGunnar Mills // attempts are left 11751e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint32_t>( 1176002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 11771e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 11781e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootAttempts", 11791e1e598dSJonathan Doman "AttemptsLeft", 1180cb13a392SEd Tanous [aResp](const boost::system::error_code ec2, 1181914e2d5dSEd Tanous const uint32_t autoRebootAttemptsLeft) { 1182cb13a392SEd Tanous if (ec2) 11836bd5a8d2SGunnar Mills { 1184cb13a392SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2; 11856bd5a8d2SGunnar Mills return; 11866bd5a8d2SGunnar Mills } 11876bd5a8d2SGunnar Mills 11886bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: " 11891e1e598dSJonathan Doman << autoRebootAttemptsLeft; 11906bd5a8d2SGunnar Mills 11916bd5a8d2SGunnar Mills aResp->res 1192002d39b4SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 11931e1e598dSJonathan Doman autoRebootAttemptsLeft; 11941e1e598dSJonathan Doman }); 11956bd5a8d2SGunnar Mills } 11966bd5a8d2SGunnar Mills else 11976bd5a8d2SGunnar Mills { 1198002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled"; 11996bd5a8d2SGunnar Mills } 12006bd5a8d2SGunnar Mills 12016bd5a8d2SGunnar Mills // Not on D-Bus. Hardcoded here: 12026bd5a8d2SGunnar Mills // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71 12036bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3; 120469f35306SGunnar Mills 120569f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 120669f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 120769f35306SGunnar Mills // RetryAttempts. 1208002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 12090fda0f12SGeorge Liu ["AutomaticRetryConfig@Redfish.AllowableValues"] = { 12100fda0f12SGeorge Liu "Disabled", "RetryAttempts"}; 12111e1e598dSJonathan Doman }); 12126bd5a8d2SGunnar Mills } 12136bd5a8d2SGunnar Mills 12146bd5a8d2SGunnar Mills /** 1215c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1216c6a620f2SGeorge Liu * 1217c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1218c6a620f2SGeorge Liu * 1219c6a620f2SGeorge Liu * @return None. 1220c6a620f2SGeorge Liu */ 12218d1b46d7Szhanghch05 inline void 12228d1b46d7Szhanghch05 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1223c6a620f2SGeorge Liu { 1224c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1225c6a620f2SGeorge Liu 12261e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 12271e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12281e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 12291e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 12301e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, const std::string& policy) { 1231c6a620f2SGeorge Liu if (ec) 1232c6a620f2SGeorge Liu { 1233c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1234c6a620f2SGeorge Liu return; 1235c6a620f2SGeorge Liu } 1236c6a620f2SGeorge Liu 12370fda0f12SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 12380fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn", 1239c6a620f2SGeorge Liu "AlwaysOn"}, 12400fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff", 1241c6a620f2SGeorge Liu "AlwaysOff"}, 12420fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore", 12434ed47cb8SMatthew Barth "LastState"}, 12444ed47cb8SMatthew Barth // Return `AlwaysOff` when power restore policy set to "None" 12454ed47cb8SMatthew Barth {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None", 12464ed47cb8SMatthew Barth "AlwaysOff"}}; 1247c6a620f2SGeorge Liu 12481e1e598dSJonathan Doman auto policyMapsIt = policyMaps.find(policy); 1249c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1250c6a620f2SGeorge Liu { 1251c6a620f2SGeorge Liu messages::internalError(aResp->res); 1252c6a620f2SGeorge Liu return; 1253c6a620f2SGeorge Liu } 1254c6a620f2SGeorge Liu 1255c6a620f2SGeorge Liu aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second; 12561e1e598dSJonathan Doman }); 1257c6a620f2SGeorge Liu } 1258c6a620f2SGeorge Liu 1259c6a620f2SGeorge Liu /** 12601981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 12611981771bSAli Ahmed * TPM is required for booting the host. 12621981771bSAli Ahmed * 12631981771bSAli Ahmed * @param[in] aResp Shared pointer for generating response message. 12641981771bSAli Ahmed * 12651981771bSAli Ahmed * @return None. 12661981771bSAli Ahmed */ 12671981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 12681981771bSAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp) 12691981771bSAli Ahmed { 12701981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 1271e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1272e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1273e99073f5SGeorge Liu dbus::utility::getSubTree( 1274e99073f5SGeorge Liu "/", 0, interfaces, 1275e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 1276b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 12771981771bSAli Ahmed if (ec) 12781981771bSAli Ahmed { 1279002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1280002d39b4SEd Tanous << ec; 12811981771bSAli Ahmed // This is an optional D-Bus object so just return if 12821981771bSAli Ahmed // error occurs 12831981771bSAli Ahmed return; 12841981771bSAli Ahmed } 128526f6976fSEd Tanous if (subtree.empty()) 12861981771bSAli Ahmed { 12871981771bSAli Ahmed // As noted above, this is an optional interface so just return 12881981771bSAli Ahmed // if there is no instance found 12891981771bSAli Ahmed return; 12901981771bSAli Ahmed } 12911981771bSAli Ahmed 12921981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 12931981771bSAli Ahmed if (subtree.size() > 1) 12941981771bSAli Ahmed { 12951981771bSAli Ahmed BMCWEB_LOG_DEBUG 12961981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 12971981771bSAli Ahmed << subtree.size(); 12981981771bSAli Ahmed // Throw an internal Error and return 12991981771bSAli Ahmed messages::internalError(aResp->res); 13001981771bSAli Ahmed return; 13011981771bSAli Ahmed } 13021981771bSAli Ahmed 13031981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 13041981771bSAli Ahmed // field 13051981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 13061981771bSAli Ahmed { 13071981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 13081981771bSAli Ahmed messages::internalError(aResp->res); 13091981771bSAli Ahmed return; 13101981771bSAli Ahmed } 13111981771bSAli Ahmed 13121981771bSAli Ahmed const std::string& path = subtree[0].first; 13131981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 13141981771bSAli Ahmed 13151981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 13161e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 13171e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 13181e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 13198a592810SEd Tanous [aResp](const boost::system::error_code ec2, bool tpmRequired) { 13208a592810SEd Tanous if (ec2) 13211981771bSAli Ahmed { 1322002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get" 13238a592810SEd Tanous << ec2; 13241981771bSAli Ahmed messages::internalError(aResp->res); 13251981771bSAli Ahmed return; 13261981771bSAli Ahmed } 13271981771bSAli Ahmed 13281e1e598dSJonathan Doman if (tpmRequired) 13291981771bSAli Ahmed { 1330002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 13311981771bSAli Ahmed "Required"; 13321981771bSAli Ahmed } 13331981771bSAli Ahmed else 13341981771bSAli Ahmed { 1335002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 13361981771bSAli Ahmed "Disabled"; 13371981771bSAli Ahmed } 13381e1e598dSJonathan Doman }); 1339e99073f5SGeorge Liu }); 13401981771bSAli Ahmed } 13411981771bSAli Ahmed 13421981771bSAli Ahmed /** 13431c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 13441c05dae3SAli Ahmed * TPM is required for booting the host. 13451c05dae3SAli Ahmed * 13461c05dae3SAli Ahmed * @param[in] aResp Shared pointer for generating response message. 13471c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 13481c05dae3SAli Ahmed * 13491c05dae3SAli Ahmed * @return None. 13501c05dae3SAli Ahmed */ 13511c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 13521c05dae3SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired) 13531c05dae3SAli Ahmed { 13541c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 1355e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1356e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1357e99073f5SGeorge Liu dbus::utility::getSubTree( 1358e99073f5SGeorge Liu "/", 0, interfaces, 1359e99073f5SGeorge Liu [aResp, 1360e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1361e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 13621c05dae3SAli Ahmed if (ec) 13631c05dae3SAli Ahmed { 1364002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1365002d39b4SEd Tanous << ec; 13661c05dae3SAli Ahmed messages::internalError(aResp->res); 13671c05dae3SAli Ahmed return; 13681c05dae3SAli Ahmed } 136926f6976fSEd Tanous if (subtree.empty()) 13701c05dae3SAli Ahmed { 13711c05dae3SAli Ahmed messages::propertyValueNotInList(aResp->res, "ComputerSystem", 13721c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 13731c05dae3SAli Ahmed return; 13741c05dae3SAli Ahmed } 13751c05dae3SAli Ahmed 13761c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 13771c05dae3SAli Ahmed if (subtree.size() > 1) 13781c05dae3SAli Ahmed { 13791c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 13801c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 13811c05dae3SAli Ahmed << subtree.size(); 13821c05dae3SAli Ahmed // Throw an internal Error and return 13831c05dae3SAli Ahmed messages::internalError(aResp->res); 13841c05dae3SAli Ahmed return; 13851c05dae3SAli Ahmed } 13861c05dae3SAli Ahmed 13871c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 13881c05dae3SAli Ahmed // field 13891c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 13901c05dae3SAli Ahmed { 13911c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 13921c05dae3SAli Ahmed messages::internalError(aResp->res); 13931c05dae3SAli Ahmed return; 13941c05dae3SAli Ahmed } 13951c05dae3SAli Ahmed 13961c05dae3SAli Ahmed const std::string& path = subtree[0].first; 13971c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 13981c05dae3SAli Ahmed 13991c05dae3SAli Ahmed if (serv.empty()) 14001c05dae3SAli Ahmed { 14011c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 14021c05dae3SAli Ahmed messages::internalError(aResp->res); 14031c05dae3SAli Ahmed return; 14041c05dae3SAli Ahmed } 14051c05dae3SAli Ahmed 14061c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 14071c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 14088a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 14098a592810SEd Tanous if (ec2) 14101c05dae3SAli Ahmed { 14110fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 14120fda0f12SGeorge Liu << "DBUS response error: Set TrustedModuleRequiredToBoot" 14138a592810SEd Tanous << ec2; 14141c05dae3SAli Ahmed messages::internalError(aResp->res); 14151c05dae3SAli Ahmed return; 14161c05dae3SAli Ahmed } 14171c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 14181c05dae3SAli Ahmed }, 14191c05dae3SAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Set", 14201c05dae3SAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1421168e20c1SEd Tanous dbus::utility::DbusVariantType(tpmRequired)); 1422e99073f5SGeorge Liu }); 14231c05dae3SAli Ahmed } 14241c05dae3SAli Ahmed 14251c05dae3SAli Ahmed /** 1426491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1427491d8ee7SSantosh Puranik * 1428491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1429cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1430cd9a4666SKonstantin Aladyshev * @return Integer error code. 1431cd9a4666SKonstantin Aladyshev */ 1432cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1433cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1434cd9a4666SKonstantin Aladyshev { 1435c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1436cd9a4666SKonstantin Aladyshev 1437c21865c4SKonstantin Aladyshev if (!bootType) 1438cd9a4666SKonstantin Aladyshev { 1439c21865c4SKonstantin Aladyshev return; 1440c21865c4SKonstantin Aladyshev } 1441c21865c4SKonstantin Aladyshev 1442cd9a4666SKonstantin Aladyshev // Source target specified 1443cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1444cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1445cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1446cd9a4666SKonstantin Aladyshev { 1447cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1448cd9a4666SKonstantin Aladyshev } 1449cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1450cd9a4666SKonstantin Aladyshev { 1451cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1452cd9a4666SKonstantin Aladyshev } 1453cd9a4666SKonstantin Aladyshev else 1454cd9a4666SKonstantin Aladyshev { 1455cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1456cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1457cd9a4666SKonstantin Aladyshev << *bootType; 1458cd9a4666SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootType, 1459cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1460cd9a4666SKonstantin Aladyshev return; 1461cd9a4666SKonstantin Aladyshev } 1462cd9a4666SKonstantin Aladyshev 1463cd9a4666SKonstantin Aladyshev // Act on validated parameters 1464cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1465cd9a4666SKonstantin Aladyshev 1466cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1467c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1468cd9a4666SKonstantin Aladyshev if (ec) 1469cd9a4666SKonstantin Aladyshev { 1470cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1471cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1472cd9a4666SKonstantin Aladyshev { 1473cd9a4666SKonstantin Aladyshev messages::resourceNotFound(aResp->res, "Set", "BootType"); 1474cd9a4666SKonstantin Aladyshev return; 1475cd9a4666SKonstantin Aladyshev } 1476cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 1477cd9a4666SKonstantin Aladyshev return; 1478cd9a4666SKonstantin Aladyshev } 1479cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1480cd9a4666SKonstantin Aladyshev }, 1481c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1482c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1483cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1484cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1485168e20c1SEd Tanous dbus::utility::DbusVariantType(bootTypeStr)); 1486cd9a4666SKonstantin Aladyshev } 1487cd9a4666SKonstantin Aladyshev 1488cd9a4666SKonstantin Aladyshev /** 1489cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1490cd9a4666SKonstantin Aladyshev * 1491cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1492c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1493c21865c4SKonstantin Aladyshev * @return Integer error code. 1494c21865c4SKonstantin Aladyshev */ 1495c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1496c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1497c21865c4SKonstantin Aladyshev { 1498c21865c4SKonstantin Aladyshev if (!bootEnable) 1499c21865c4SKonstantin Aladyshev { 1500c21865c4SKonstantin Aladyshev return; 1501c21865c4SKonstantin Aladyshev } 1502c21865c4SKonstantin Aladyshev // Source target specified 1503c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1504c21865c4SKonstantin Aladyshev 1505c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1506c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1507c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1508c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1509c21865c4SKonstantin Aladyshev { 1510c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1511c21865c4SKonstantin Aladyshev } 1512c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1513c21865c4SKonstantin Aladyshev { 1514c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1515c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1516c21865c4SKonstantin Aladyshev } 1517c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1518c21865c4SKonstantin Aladyshev { 1519c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1520c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1521c21865c4SKonstantin Aladyshev } 1522c21865c4SKonstantin Aladyshev else 1523c21865c4SKonstantin Aladyshev { 15240fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 15250fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideEnabled: " 1526c21865c4SKonstantin Aladyshev << *bootEnable; 1527c21865c4SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootEnable, 1528c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1529c21865c4SKonstantin Aladyshev return; 1530c21865c4SKonstantin Aladyshev } 1531c21865c4SKonstantin Aladyshev 1532c21865c4SKonstantin Aladyshev // Act on validated parameters 1533c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1534c21865c4SKonstantin Aladyshev 1535c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 15368a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 15378a592810SEd Tanous if (ec2) 1538c21865c4SKonstantin Aladyshev { 15398a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1540c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1541c21865c4SKonstantin Aladyshev return; 1542c21865c4SKonstantin Aladyshev } 1543c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1544c21865c4SKonstantin Aladyshev }, 1545c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1546c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1547c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1548c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1549168e20c1SEd Tanous dbus::utility::DbusVariantType(bootOverrideEnable)); 1550c21865c4SKonstantin Aladyshev 1551c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1552c21865c4SKonstantin Aladyshev { 1553c21865c4SKonstantin Aladyshev return; 1554c21865c4SKonstantin Aladyshev } 1555c21865c4SKonstantin Aladyshev 1556c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1557c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1558c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1559c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1560c21865c4SKonstantin Aladyshev 1561c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1562c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1563c21865c4SKonstantin Aladyshev if (ec) 1564c21865c4SKonstantin Aladyshev { 1565c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1566c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1567c21865c4SKonstantin Aladyshev return; 1568c21865c4SKonstantin Aladyshev } 1569c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1570c21865c4SKonstantin Aladyshev }, 1571c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1572c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1573c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1574c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1575168e20c1SEd Tanous dbus::utility::DbusVariantType(!bootOverridePersistent)); 1576c21865c4SKonstantin Aladyshev } 1577c21865c4SKonstantin Aladyshev 1578c21865c4SKonstantin Aladyshev /** 1579c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1580c21865c4SKonstantin Aladyshev * 1581c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1582491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1583491d8ee7SSantosh Puranik * 1584265c1602SJohnathan Mantey * @return Integer error code. 1585491d8ee7SSantosh Puranik */ 1586cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1587cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1588491d8ee7SSantosh Puranik { 1589c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1590c21865c4SKonstantin Aladyshev std::string bootModeStr; 1591944ffaf9SJohnathan Mantey 1592c21865c4SKonstantin Aladyshev if (!bootSource) 1593491d8ee7SSantosh Puranik { 1594c21865c4SKonstantin Aladyshev return; 1595c21865c4SKonstantin Aladyshev } 1596c21865c4SKonstantin Aladyshev 1597491d8ee7SSantosh Puranik // Source target specified 1598491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1599491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1600e662eae8SEd Tanous if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) != 1601e662eae8SEd Tanous 0) 1602491d8ee7SSantosh Puranik { 1603944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1604944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1605491d8ee7SSantosh Puranik << *bootSource; 1606491d8ee7SSantosh Puranik messages::propertyValueNotInList(aResp->res, *bootSource, 1607491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1608491d8ee7SSantosh Puranik return; 1609491d8ee7SSantosh Puranik } 1610491d8ee7SSantosh Puranik 1611944ffaf9SJohnathan Mantey // Act on validated parameters 1612944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1613944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1614944ffaf9SJohnathan Mantey 1615491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1616491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1617491d8ee7SSantosh Puranik if (ec) 1618491d8ee7SSantosh Puranik { 1619491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1620491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1621491d8ee7SSantosh Puranik return; 1622491d8ee7SSantosh Puranik } 1623491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1624491d8ee7SSantosh Puranik }, 1625c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1626c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1627491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1628491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1629168e20c1SEd Tanous dbus::utility::DbusVariantType(bootSourceStr)); 1630944ffaf9SJohnathan Mantey 1631491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1632491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1633491d8ee7SSantosh Puranik if (ec) 1634491d8ee7SSantosh Puranik { 1635491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1636491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1637491d8ee7SSantosh Puranik return; 1638491d8ee7SSantosh Puranik } 1639491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1640491d8ee7SSantosh Puranik }, 1641c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1642c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1643491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1644491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1645168e20c1SEd Tanous dbus::utility::DbusVariantType(bootModeStr)); 1646cd9a4666SKonstantin Aladyshev } 1647944ffaf9SJohnathan Mantey 1648cd9a4666SKonstantin Aladyshev /** 1649c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1650491d8ee7SSantosh Puranik * 1651491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1652491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1653cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1654491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1655491d8ee7SSantosh Puranik * 1656265c1602SJohnathan Mantey * @return Integer error code. 1657491d8ee7SSantosh Puranik */ 1658c21865c4SKonstantin Aladyshev 1659c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1660c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1661c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1662c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1663491d8ee7SSantosh Puranik { 1664491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1665491d8ee7SSantosh Puranik 1666c21865c4SKonstantin Aladyshev setBootModeOrSource(aResp, bootSource); 1667c21865c4SKonstantin Aladyshev setBootType(aResp, bootType); 1668c21865c4SKonstantin Aladyshev setBootEnable(aResp, bootEnable); 1669491d8ee7SSantosh Puranik } 1670491d8ee7SSantosh Puranik 1671c6a620f2SGeorge Liu /** 167298e386ecSGunnar Mills * @brief Sets AssetTag 167398e386ecSGunnar Mills * 167498e386ecSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 167598e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 167698e386ecSGunnar Mills * 167798e386ecSGunnar Mills * @return None. 167898e386ecSGunnar Mills */ 16798d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 168098e386ecSGunnar Mills const std::string& assetTag) 168198e386ecSGunnar Mills { 1682e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1683e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1684e99073f5SGeorge Liu dbus::utility::getSubTree( 1685e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1686b9d36b47SEd Tanous [aResp, 1687e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1688b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 168998e386ecSGunnar Mills if (ec) 169098e386ecSGunnar Mills { 169198e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 169298e386ecSGunnar Mills messages::internalError(aResp->res); 169398e386ecSGunnar Mills return; 169498e386ecSGunnar Mills } 169526f6976fSEd Tanous if (subtree.empty()) 169698e386ecSGunnar Mills { 169798e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 169898e386ecSGunnar Mills messages::internalError(aResp->res); 169998e386ecSGunnar Mills return; 170098e386ecSGunnar Mills } 170198e386ecSGunnar Mills // Assume only 1 system D-Bus object 170298e386ecSGunnar Mills // Throw an error if there is more than 1 170398e386ecSGunnar Mills if (subtree.size() > 1) 170498e386ecSGunnar Mills { 170598e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 170698e386ecSGunnar Mills messages::internalError(aResp->res); 170798e386ecSGunnar Mills return; 170898e386ecSGunnar Mills } 170998e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 171098e386ecSGunnar Mills { 171198e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 171298e386ecSGunnar Mills messages::internalError(aResp->res); 171398e386ecSGunnar Mills return; 171498e386ecSGunnar Mills } 171598e386ecSGunnar Mills 171698e386ecSGunnar Mills const std::string& path = subtree[0].first; 171798e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 171898e386ecSGunnar Mills 171998e386ecSGunnar Mills if (service.empty()) 172098e386ecSGunnar Mills { 172198e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 172298e386ecSGunnar Mills messages::internalError(aResp->res); 172398e386ecSGunnar Mills return; 172498e386ecSGunnar Mills } 172598e386ecSGunnar Mills 172698e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 172798e386ecSGunnar Mills [aResp](const boost::system::error_code ec2) { 172898e386ecSGunnar Mills if (ec2) 172998e386ecSGunnar Mills { 1730002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set " 1731002d39b4SEd Tanous << ec2; 173298e386ecSGunnar Mills messages::internalError(aResp->res); 173398e386ecSGunnar Mills return; 173498e386ecSGunnar Mills } 173598e386ecSGunnar Mills }, 173698e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 173798e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 1738168e20c1SEd Tanous dbus::utility::DbusVariantType(assetTag)); 1739e99073f5SGeorge Liu }); 174098e386ecSGunnar Mills } 174198e386ecSGunnar Mills 174298e386ecSGunnar Mills /** 174369f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 174469f35306SGunnar Mills * 174569f35306SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 174669f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 174769f35306SGunnar Mills * 174869f35306SGunnar Mills * @return None. 174969f35306SGunnar Mills */ 17508d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1751f23b7296SEd Tanous const std::string& automaticRetryConfig) 175269f35306SGunnar Mills { 175369f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 175469f35306SGunnar Mills 175569f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1756543f4400SEd Tanous bool autoRebootEnabled = false; 175769f35306SGunnar Mills 175869f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 175969f35306SGunnar Mills { 176069f35306SGunnar Mills autoRebootEnabled = false; 176169f35306SGunnar Mills } 176269f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 176369f35306SGunnar Mills { 176469f35306SGunnar Mills autoRebootEnabled = true; 176569f35306SGunnar Mills } 176669f35306SGunnar Mills else 176769f35306SGunnar Mills { 17680fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: " 176969f35306SGunnar Mills << automaticRetryConfig; 177069f35306SGunnar Mills messages::propertyValueNotInList(aResp->res, automaticRetryConfig, 177169f35306SGunnar Mills "AutomaticRetryConfig"); 177269f35306SGunnar Mills return; 177369f35306SGunnar Mills } 177469f35306SGunnar Mills 177569f35306SGunnar Mills crow::connections::systemBus->async_method_call( 177669f35306SGunnar Mills [aResp](const boost::system::error_code ec) { 177769f35306SGunnar Mills if (ec) 177869f35306SGunnar Mills { 177969f35306SGunnar Mills messages::internalError(aResp->res); 178069f35306SGunnar Mills return; 178169f35306SGunnar Mills } 178269f35306SGunnar Mills }, 178369f35306SGunnar Mills "xyz.openbmc_project.Settings", 178469f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 178569f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 178669f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1787168e20c1SEd Tanous dbus::utility::DbusVariantType(autoRebootEnabled)); 178869f35306SGunnar Mills } 178969f35306SGunnar Mills 179069f35306SGunnar Mills /** 1791c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1792c6a620f2SGeorge Liu * 1793c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1794c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1795c6a620f2SGeorge Liu * 1796c6a620f2SGeorge Liu * @return None. 1797c6a620f2SGeorge Liu */ 17988d1b46d7Szhanghch05 inline void 17998d1b46d7Szhanghch05 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 18004e69c904SGunnar Mills const std::string& policy) 1801c6a620f2SGeorge Liu { 1802c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1803c6a620f2SGeorge Liu 1804c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 18050fda0f12SGeorge Liu {"AlwaysOn", 18060fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"}, 18070fda0f12SGeorge Liu {"AlwaysOff", 18080fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"}, 18090fda0f12SGeorge Liu {"LastState", 18100fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}}; 1811c6a620f2SGeorge Liu 1812c6a620f2SGeorge Liu std::string powerRestorPolicy; 1813c6a620f2SGeorge Liu 18144e69c904SGunnar Mills auto policyMapsIt = policyMaps.find(policy); 1815c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1816c6a620f2SGeorge Liu { 18174e69c904SGunnar Mills messages::propertyValueNotInList(aResp->res, policy, 18184e69c904SGunnar Mills "PowerRestorePolicy"); 1819c6a620f2SGeorge Liu return; 1820c6a620f2SGeorge Liu } 1821c6a620f2SGeorge Liu 1822c6a620f2SGeorge Liu powerRestorPolicy = policyMapsIt->second; 1823c6a620f2SGeorge Liu 1824c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1825c6a620f2SGeorge Liu [aResp](const boost::system::error_code ec) { 1826c6a620f2SGeorge Liu if (ec) 1827c6a620f2SGeorge Liu { 1828c6a620f2SGeorge Liu messages::internalError(aResp->res); 1829c6a620f2SGeorge Liu return; 1830c6a620f2SGeorge Liu } 1831c6a620f2SGeorge Liu }, 1832c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1833c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1834c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1835c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1836168e20c1SEd Tanous dbus::utility::DbusVariantType(powerRestorPolicy)); 1837c6a620f2SGeorge Liu } 1838c6a620f2SGeorge Liu 1839a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 1840a6349918SAppaRao Puli /** 1841a6349918SAppaRao Puli * @brief Retrieves provisioning status 1842a6349918SAppaRao Puli * 1843a6349918SAppaRao Puli * @param[in] aResp Shared pointer for completing asynchronous calls. 1844a6349918SAppaRao Puli * 1845a6349918SAppaRao Puli * @return None. 1846a6349918SAppaRao Puli */ 18478d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp) 1848a6349918SAppaRao Puli { 1849a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 1850bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1851bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1852bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 1853a6349918SAppaRao Puli [aResp](const boost::system::error_code ec, 1854b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1855b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1856b99fb1a9SAppaRao Puli aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 185750626f4fSJames Feist aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 185850626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 185950626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 186050626f4fSJames Feist 1861a6349918SAppaRao Puli if (ec) 1862a6349918SAppaRao Puli { 1863a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1864b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1865b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1866a6349918SAppaRao Puli return; 1867a6349918SAppaRao Puli } 1868a6349918SAppaRao Puli 1869a6349918SAppaRao Puli const bool* provState = nullptr; 1870a6349918SAppaRao Puli const bool* lockState = nullptr; 1871bc1d29deSKrzysztof Grobelny 1872bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 18730d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 18740d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 1875bc1d29deSKrzysztof Grobelny 1876bc1d29deSKrzysztof Grobelny if (!success) 1877a6349918SAppaRao Puli { 1878bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 1879bc1d29deSKrzysztof Grobelny return; 1880a6349918SAppaRao Puli } 1881a6349918SAppaRao Puli 1882a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 1883a6349918SAppaRao Puli { 1884a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 1885a6349918SAppaRao Puli messages::internalError(aResp->res); 1886a6349918SAppaRao Puli return; 1887a6349918SAppaRao Puli } 1888a6349918SAppaRao Puli 1889a6349918SAppaRao Puli if (*provState == true) 1890a6349918SAppaRao Puli { 1891a6349918SAppaRao Puli if (*lockState == true) 1892a6349918SAppaRao Puli { 1893a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 1894a6349918SAppaRao Puli } 1895a6349918SAppaRao Puli else 1896a6349918SAppaRao Puli { 1897a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 1898a6349918SAppaRao Puli } 1899a6349918SAppaRao Puli } 1900a6349918SAppaRao Puli else 1901a6349918SAppaRao Puli { 1902a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1903a6349918SAppaRao Puli } 1904bc1d29deSKrzysztof Grobelny }); 1905a6349918SAppaRao Puli } 1906a6349918SAppaRao Puli #endif 1907a6349918SAppaRao Puli 1908491d8ee7SSantosh Puranik /** 19093a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 19103a2d0424SChris Cain * 19113a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 19123a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 19133a2d0424SChris Cain * 19143a2d0424SChris Cain * @return None. 19153a2d0424SChris Cain */ 19163a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 19173a2d0424SChris Cain const std::string& modeValue) 19183a2d0424SChris Cain { 19190fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 19203a2d0424SChris Cain { 19213a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "Static"; 19223a2d0424SChris Cain } 19230fda0f12SGeorge Liu else if ( 19240fda0f12SGeorge Liu modeValue == 19250fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 19263a2d0424SChris Cain { 19273a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 19283a2d0424SChris Cain } 19290fda0f12SGeorge Liu else if (modeValue == 19300fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 19313a2d0424SChris Cain { 19323a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "PowerSaving"; 19333a2d0424SChris Cain } 19340fda0f12SGeorge Liu else if (modeValue == 19350fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 19363a2d0424SChris Cain { 19373a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "OEM"; 19383a2d0424SChris Cain } 19393a2d0424SChris Cain else 19403a2d0424SChris Cain { 19413a2d0424SChris Cain // Any other values would be invalid 19423a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 19433a2d0424SChris Cain messages::internalError(aResp->res); 19443a2d0424SChris Cain } 19453a2d0424SChris Cain } 19463a2d0424SChris Cain 19473a2d0424SChris Cain /** 19483a2d0424SChris Cain * @brief Retrieves system power mode 19493a2d0424SChris Cain * 19503a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 19513a2d0424SChris Cain * 19523a2d0424SChris Cain * @return None. 19533a2d0424SChris Cain */ 19543a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 19553a2d0424SChris Cain { 19563a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 19573a2d0424SChris Cain 19583a2d0424SChris Cain // Get Power Mode object path: 1959e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1960e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 1961e99073f5SGeorge Liu dbus::utility::getSubTree( 1962e99073f5SGeorge Liu "/", 0, interfaces, 1963e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 1964b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 19653a2d0424SChris Cain if (ec) 19663a2d0424SChris Cain { 1967002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 1968002d39b4SEd Tanous << ec; 19693a2d0424SChris Cain // This is an optional D-Bus object so just return if 19703a2d0424SChris Cain // error occurs 19713a2d0424SChris Cain return; 19723a2d0424SChris Cain } 19733a2d0424SChris Cain if (subtree.empty()) 19743a2d0424SChris Cain { 19753a2d0424SChris Cain // As noted above, this is an optional interface so just return 19763a2d0424SChris Cain // if there is no instance found 19773a2d0424SChris Cain return; 19783a2d0424SChris Cain } 19793a2d0424SChris Cain if (subtree.size() > 1) 19803a2d0424SChris Cain { 19813a2d0424SChris Cain // More then one PowerMode object is not supported and is an 19823a2d0424SChris Cain // error 19833a2d0424SChris Cain BMCWEB_LOG_DEBUG 19843a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 19853a2d0424SChris Cain << subtree.size(); 19863a2d0424SChris Cain messages::internalError(aResp->res); 19873a2d0424SChris Cain return; 19883a2d0424SChris Cain } 19893a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 19903a2d0424SChris Cain { 19913a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 19923a2d0424SChris Cain messages::internalError(aResp->res); 19933a2d0424SChris Cain return; 19943a2d0424SChris Cain } 19953a2d0424SChris Cain const std::string& path = subtree[0].first; 19963a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 19973a2d0424SChris Cain if (service.empty()) 19983a2d0424SChris Cain { 19993a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 20003a2d0424SChris Cain messages::internalError(aResp->res); 20013a2d0424SChris Cain return; 20023a2d0424SChris Cain } 20033a2d0424SChris Cain // Valid Power Mode object found, now read the current value 20041e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 20051e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 20061e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 20078a592810SEd Tanous [aResp](const boost::system::error_code ec2, 20081e1e598dSJonathan Doman const std::string& pmode) { 20098a592810SEd Tanous if (ec2) 20103a2d0424SChris Cain { 2011002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: " 20128a592810SEd Tanous << ec2; 20133a2d0424SChris Cain messages::internalError(aResp->res); 20143a2d0424SChris Cain return; 20153a2d0424SChris Cain } 20163a2d0424SChris Cain 2017002d39b4SEd Tanous aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2018002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 20193a2d0424SChris Cain 20201e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 20211e1e598dSJonathan Doman translatePowerMode(aResp, pmode); 20221e1e598dSJonathan Doman }); 2023e99073f5SGeorge Liu }); 20243a2d0424SChris Cain } 20253a2d0424SChris Cain 20263a2d0424SChris Cain /** 20273a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 20283a2d0424SChris Cain * name associated with that string 20293a2d0424SChris Cain * 20303a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20313a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 20323a2d0424SChris Cain * 20333a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 20343a2d0424SChris Cain */ 20353a2d0424SChris Cain inline std::string 20363a2d0424SChris Cain validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 20373a2d0424SChris Cain const std::string& modeString) 20383a2d0424SChris Cain { 20393a2d0424SChris Cain std::string mode; 20403a2d0424SChris Cain 20413a2d0424SChris Cain if (modeString == "Static") 20423a2d0424SChris Cain { 20433a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 20443a2d0424SChris Cain } 20453a2d0424SChris Cain else if (modeString == "MaximumPerformance") 20463a2d0424SChris Cain { 20470fda0f12SGeorge Liu mode = 20480fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 20493a2d0424SChris Cain } 20503a2d0424SChris Cain else if (modeString == "PowerSaving") 20513a2d0424SChris Cain { 20523a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 20533a2d0424SChris Cain } 20543a2d0424SChris Cain else 20553a2d0424SChris Cain { 20563a2d0424SChris Cain messages::propertyValueNotInList(aResp->res, modeString, "PowerMode"); 20573a2d0424SChris Cain } 20583a2d0424SChris Cain return mode; 20593a2d0424SChris Cain } 20603a2d0424SChris Cain 20613a2d0424SChris Cain /** 20623a2d0424SChris Cain * @brief Sets system power mode. 20633a2d0424SChris Cain * 20643a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20653a2d0424SChris Cain * @param[in] pmode System power mode from request. 20663a2d0424SChris Cain * 20673a2d0424SChris Cain * @return None. 20683a2d0424SChris Cain */ 20693a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 20703a2d0424SChris Cain const std::string& pmode) 20713a2d0424SChris Cain { 20723a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 20733a2d0424SChris Cain 20743a2d0424SChris Cain std::string powerMode = validatePowerMode(aResp, pmode); 20753a2d0424SChris Cain if (powerMode.empty()) 20763a2d0424SChris Cain { 20773a2d0424SChris Cain return; 20783a2d0424SChris Cain } 20793a2d0424SChris Cain 20803a2d0424SChris Cain // Get Power Mode object path: 2081e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2082e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2083e99073f5SGeorge Liu dbus::utility::getSubTree( 2084e99073f5SGeorge Liu "/", 0, interfaces, 2085b9d36b47SEd Tanous [aResp, 2086e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2087b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 20883a2d0424SChris Cain if (ec) 20893a2d0424SChris Cain { 2090002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2091002d39b4SEd Tanous << ec; 20923a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 20933a2d0424SChris Cain messages::internalError(aResp->res); 20943a2d0424SChris Cain return; 20953a2d0424SChris Cain } 20963a2d0424SChris Cain if (subtree.empty()) 20973a2d0424SChris Cain { 20983a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 20993a2d0424SChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 21003a2d0424SChris Cain "PowerMode"); 21013a2d0424SChris Cain return; 21023a2d0424SChris Cain } 21033a2d0424SChris Cain if (subtree.size() > 1) 21043a2d0424SChris Cain { 21053a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21063a2d0424SChris Cain // error 21073a2d0424SChris Cain BMCWEB_LOG_DEBUG 21083a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 21093a2d0424SChris Cain << subtree.size(); 21103a2d0424SChris Cain messages::internalError(aResp->res); 21113a2d0424SChris Cain return; 21123a2d0424SChris Cain } 21133a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21143a2d0424SChris Cain { 21153a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 21163a2d0424SChris Cain messages::internalError(aResp->res); 21173a2d0424SChris Cain return; 21183a2d0424SChris Cain } 21193a2d0424SChris Cain const std::string& path = subtree[0].first; 21203a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21213a2d0424SChris Cain if (service.empty()) 21223a2d0424SChris Cain { 21233a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 21243a2d0424SChris Cain messages::internalError(aResp->res); 21253a2d0424SChris Cain return; 21263a2d0424SChris Cain } 21273a2d0424SChris Cain 21283a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 21293a2d0424SChris Cain << path; 21303a2d0424SChris Cain 21313a2d0424SChris Cain // Set the Power Mode property 21323a2d0424SChris Cain crow::connections::systemBus->async_method_call( 21338a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 21348a592810SEd Tanous if (ec2) 21353a2d0424SChris Cain { 21363a2d0424SChris Cain messages::internalError(aResp->res); 21373a2d0424SChris Cain return; 21383a2d0424SChris Cain } 21393a2d0424SChris Cain }, 21403a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 21413a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2142168e20c1SEd Tanous dbus::utility::DbusVariantType(powerMode)); 2143e99073f5SGeorge Liu }); 21443a2d0424SChris Cain } 21453a2d0424SChris Cain 21463a2d0424SChris Cain /** 214751709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 214851709ffdSYong Li * 214951709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 215051709ffdSYong Li * 215151709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 215251709ffdSYong Li * translation cannot be done, returns an empty string. 215351709ffdSYong Li */ 215423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 215551709ffdSYong Li { 215651709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 215751709ffdSYong Li { 215851709ffdSYong Li return "None"; 215951709ffdSYong Li } 21603174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 216151709ffdSYong Li { 216251709ffdSYong Li return "ResetSystem"; 216351709ffdSYong Li } 21643174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 216551709ffdSYong Li { 216651709ffdSYong Li return "PowerDown"; 216751709ffdSYong Li } 21683174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 216951709ffdSYong Li { 217051709ffdSYong Li return "PowerCycle"; 217151709ffdSYong Li } 217251709ffdSYong Li 217351709ffdSYong Li return ""; 217451709ffdSYong Li } 217551709ffdSYong Li 217651709ffdSYong Li /** 2177c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2178c45f0082SYong Li * 2179c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2180c45f0082SYong Li * 2181c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2182c45f0082SYong Li *If translation cannot be done, returns an empty string. 2183c45f0082SYong Li */ 2184c45f0082SYong Li 218523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2186c45f0082SYong Li { 2187c45f0082SYong Li if (rfAction == "None") 2188c45f0082SYong Li { 2189c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2190c45f0082SYong Li } 21913174e4dfSEd Tanous if (rfAction == "PowerCycle") 2192c45f0082SYong Li { 2193c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2194c45f0082SYong Li } 21953174e4dfSEd Tanous if (rfAction == "PowerDown") 2196c45f0082SYong Li { 2197c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2198c45f0082SYong Li } 21993174e4dfSEd Tanous if (rfAction == "ResetSystem") 2200c45f0082SYong Li { 2201c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2202c45f0082SYong Li } 2203c45f0082SYong Li 2204c45f0082SYong Li return ""; 2205c45f0082SYong Li } 2206c45f0082SYong Li 2207c45f0082SYong Li /** 220851709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 220951709ffdSYong Li * 221051709ffdSYong Li * @param[in] aResp Shared pointer for completing asynchronous calls. 221151709ffdSYong Li * 221251709ffdSYong Li * @return None. 221351709ffdSYong Li */ 22148d1b46d7Szhanghch05 inline void 22158d1b46d7Szhanghch05 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 221651709ffdSYong Li { 221751709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 2218bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2219bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2220bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2221bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 222251709ffdSYong Li [aResp](const boost::system::error_code ec, 2223b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 222451709ffdSYong Li if (ec) 222551709ffdSYong Li { 222651709ffdSYong Li // watchdog service is stopped 222751709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 222851709ffdSYong Li return; 222951709ffdSYong Li } 223051709ffdSYong Li 223151709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 223251709ffdSYong Li 223351709ffdSYong Li nlohmann::json& hostWatchdogTimer = 223451709ffdSYong Li aResp->res.jsonValue["HostWatchdogTimer"]; 223551709ffdSYong Li 223651709ffdSYong Li // watchdog service is running/enabled 223751709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 223851709ffdSYong Li 2239bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2240bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 224151709ffdSYong Li 2242bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2243bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2244bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2245bc1d29deSKrzysztof Grobelny 2246bc1d29deSKrzysztof Grobelny if (!success) 224751709ffdSYong Li { 224851709ffdSYong Li messages::internalError(aResp->res); 2249601af5edSChicago Duan return; 225051709ffdSYong Li } 225151709ffdSYong Li 2252bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 225351709ffdSYong Li { 2254bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 225551709ffdSYong Li } 225651709ffdSYong Li 2257bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2258bc1d29deSKrzysztof Grobelny { 2259bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 226051709ffdSYong Li if (action.empty()) 226151709ffdSYong Li { 226251709ffdSYong Li messages::internalError(aResp->res); 2263601af5edSChicago Duan return; 226451709ffdSYong Li } 226551709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 226651709ffdSYong Li } 2267bc1d29deSKrzysztof Grobelny }); 226851709ffdSYong Li } 226951709ffdSYong Li 227051709ffdSYong Li /** 2271c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2272c45f0082SYong Li * 2273c45f0082SYong Li * @param[in] aResp Shared pointer for generating response message. 2274c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2275c45f0082SYong Li * RF request. 2276c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2277c45f0082SYong Li * 2278c45f0082SYong Li * @return None. 2279c45f0082SYong Li */ 22808d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 2281c45f0082SYong Li const std::optional<bool> wdtEnable, 2282c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2283c45f0082SYong Li { 2284c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2285c45f0082SYong Li 2286c45f0082SYong Li if (wdtTimeOutAction) 2287c45f0082SYong Li { 2288c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2289c45f0082SYong Li // check if TimeOut Action is Valid 2290c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2291c45f0082SYong Li { 2292c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2293c45f0082SYong Li << *wdtTimeOutAction; 2294c45f0082SYong Li messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction, 2295c45f0082SYong Li "TimeoutAction"); 2296c45f0082SYong Li return; 2297c45f0082SYong Li } 2298c45f0082SYong Li 2299c45f0082SYong Li crow::connections::systemBus->async_method_call( 2300c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2301c45f0082SYong Li if (ec) 2302c45f0082SYong Li { 2303c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2304c45f0082SYong Li messages::internalError(aResp->res); 2305c45f0082SYong Li return; 2306c45f0082SYong Li } 2307c45f0082SYong Li }, 2308c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2309c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2310c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2311c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2312168e20c1SEd Tanous dbus::utility::DbusVariantType(wdtTimeOutActStr)); 2313c45f0082SYong Li } 2314c45f0082SYong Li 2315c45f0082SYong Li if (wdtEnable) 2316c45f0082SYong Li { 2317c45f0082SYong Li crow::connections::systemBus->async_method_call( 2318c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2319c45f0082SYong Li if (ec) 2320c45f0082SYong Li { 2321c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2322c45f0082SYong Li messages::internalError(aResp->res); 2323c45f0082SYong Li return; 2324c45f0082SYong Li } 2325c45f0082SYong Li }, 2326c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2327c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2328c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2329c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2330168e20c1SEd Tanous dbus::utility::DbusVariantType(*wdtEnable)); 2331c45f0082SYong Li } 2332c45f0082SYong Li } 2333c45f0082SYong Li 233437bbf98cSChris Cain /** 233537bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 233637bbf98cSChris Cain * 233737bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 233837bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 233937bbf98cSChris Cain * 234037bbf98cSChris Cain * @return true if successful 234137bbf98cSChris Cain */ 23421e5b7c88SJiaqing Zhao inline bool 23431e5b7c88SJiaqing Zhao parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 23441e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 234537bbf98cSChris Cain { 2346bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2347bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2348bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2349bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2350bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2351bc1d29deSKrzysztof Grobelny 2352bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2353bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2354bc1d29deSKrzysztof Grobelny "EnterUtilizationPercent", enterUtilizationPercent, 2355bc1d29deSKrzysztof Grobelny "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime", 2356bc1d29deSKrzysztof Grobelny exitDwellTime); 2357bc1d29deSKrzysztof Grobelny 2358bc1d29deSKrzysztof Grobelny if (!success) 235937bbf98cSChris Cain { 236037bbf98cSChris Cain return false; 236137bbf98cSChris Cain } 2362bc1d29deSKrzysztof Grobelny 2363bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 236437bbf98cSChris Cain { 2365bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 236637bbf98cSChris Cain } 2367bc1d29deSKrzysztof Grobelny 2368bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 236937bbf98cSChris Cain { 2370bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2371bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 237237bbf98cSChris Cain } 2373bc1d29deSKrzysztof Grobelny 2374bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2375bc1d29deSKrzysztof Grobelny { 2376bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 237737bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 237837bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 237937bbf98cSChris Cain .count(); 238037bbf98cSChris Cain } 2381bc1d29deSKrzysztof Grobelny 2382bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 238337bbf98cSChris Cain { 2384bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2385bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 238637bbf98cSChris Cain } 2387bc1d29deSKrzysztof Grobelny 2388bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 238937bbf98cSChris Cain { 2390bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 239137bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 239237bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 239337bbf98cSChris Cain .count(); 239437bbf98cSChris Cain } 239537bbf98cSChris Cain 239637bbf98cSChris Cain return true; 239737bbf98cSChris Cain } 239837bbf98cSChris Cain 239937bbf98cSChris Cain /** 240037bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 240137bbf98cSChris Cain * 240237bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 240337bbf98cSChris Cain * 240437bbf98cSChris Cain * @return None. 240537bbf98cSChris Cain */ 240637bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 240737bbf98cSChris Cain { 240837bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 240937bbf98cSChris Cain 241037bbf98cSChris Cain // Get IdlePowerSaver object path: 2411e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2412e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2413e99073f5SGeorge Liu dbus::utility::getSubTree( 2414e99073f5SGeorge Liu "/", 0, interfaces, 2415e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 2416b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 241737bbf98cSChris Cain if (ec) 241837bbf98cSChris Cain { 241937bbf98cSChris Cain BMCWEB_LOG_DEBUG 242037bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 242137bbf98cSChris Cain << ec; 242237bbf98cSChris Cain messages::internalError(aResp->res); 242337bbf98cSChris Cain return; 242437bbf98cSChris Cain } 242537bbf98cSChris Cain if (subtree.empty()) 242637bbf98cSChris Cain { 242737bbf98cSChris Cain // This is an optional interface so just return 242837bbf98cSChris Cain // if there is no instance found 242937bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 243037bbf98cSChris Cain return; 243137bbf98cSChris Cain } 243237bbf98cSChris Cain if (subtree.size() > 1) 243337bbf98cSChris Cain { 243437bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 243537bbf98cSChris Cain // is an error 243637bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 243737bbf98cSChris Cain "Power.IdlePowerSaver objects: " 243837bbf98cSChris Cain << subtree.size(); 243937bbf98cSChris Cain messages::internalError(aResp->res); 244037bbf98cSChris Cain return; 244137bbf98cSChris Cain } 244237bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 244337bbf98cSChris Cain { 244437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 244537bbf98cSChris Cain messages::internalError(aResp->res); 244637bbf98cSChris Cain return; 244737bbf98cSChris Cain } 244837bbf98cSChris Cain const std::string& path = subtree[0].first; 244937bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 245037bbf98cSChris Cain if (service.empty()) 245137bbf98cSChris Cain { 2452002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 245337bbf98cSChris Cain messages::internalError(aResp->res); 245437bbf98cSChris Cain return; 245537bbf98cSChris Cain } 245637bbf98cSChris Cain 245737bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2458bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2459bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2460bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 24618a592810SEd Tanous [aResp](const boost::system::error_code ec2, 24621e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 24638a592810SEd Tanous if (ec2) 246437bbf98cSChris Cain { 246537bbf98cSChris Cain BMCWEB_LOG_ERROR 24668a592810SEd Tanous << "DBUS response error on IdlePowerSaver GetAll: " << ec2; 246737bbf98cSChris Cain messages::internalError(aResp->res); 246837bbf98cSChris Cain return; 246937bbf98cSChris Cain } 247037bbf98cSChris Cain 2471e05aec50SEd Tanous if (!parseIpsProperties(aResp, properties)) 247237bbf98cSChris Cain { 247337bbf98cSChris Cain messages::internalError(aResp->res); 247437bbf98cSChris Cain return; 247537bbf98cSChris Cain } 2476bc1d29deSKrzysztof Grobelny }); 2477e99073f5SGeorge Liu }); 247837bbf98cSChris Cain 247937bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 248037bbf98cSChris Cain } 248137bbf98cSChris Cain 248237bbf98cSChris Cain /** 248337bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 248437bbf98cSChris Cain * 248537bbf98cSChris Cain * @param[in] aResp Shared pointer for generating response message. 248637bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 248737bbf98cSChris Cain * RF request. 248837bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 248937bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 249037bbf98cSChris Cain * before entering idle state. 249137bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 249237bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 249337bbf98cSChris Cain * before exiting idle state 249437bbf98cSChris Cain * 249537bbf98cSChris Cain * @return None. 249637bbf98cSChris Cain */ 249737bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 249837bbf98cSChris Cain const std::optional<bool> ipsEnable, 249937bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 250037bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 250137bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 250237bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 250337bbf98cSChris Cain { 250437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 250537bbf98cSChris Cain 250637bbf98cSChris Cain // Get IdlePowerSaver object path: 2507e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2508e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2509e99073f5SGeorge Liu dbus::utility::getSubTree( 2510e99073f5SGeorge Liu "/", 0, interfaces, 251137bbf98cSChris Cain [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2512e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2513b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 251437bbf98cSChris Cain if (ec) 251537bbf98cSChris Cain { 251637bbf98cSChris Cain BMCWEB_LOG_DEBUG 251737bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 251837bbf98cSChris Cain << ec; 251937bbf98cSChris Cain messages::internalError(aResp->res); 252037bbf98cSChris Cain return; 252137bbf98cSChris Cain } 252237bbf98cSChris Cain if (subtree.empty()) 252337bbf98cSChris Cain { 252437bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 252537bbf98cSChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 252637bbf98cSChris Cain "IdlePowerSaver"); 252737bbf98cSChris Cain return; 252837bbf98cSChris Cain } 252937bbf98cSChris Cain if (subtree.size() > 1) 253037bbf98cSChris Cain { 253137bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 253237bbf98cSChris Cain // is an error 25330fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 25340fda0f12SGeorge Liu << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: " 253537bbf98cSChris Cain << subtree.size(); 253637bbf98cSChris Cain messages::internalError(aResp->res); 253737bbf98cSChris Cain return; 253837bbf98cSChris Cain } 253937bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 254037bbf98cSChris Cain { 254137bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 254237bbf98cSChris Cain messages::internalError(aResp->res); 254337bbf98cSChris Cain return; 254437bbf98cSChris Cain } 254537bbf98cSChris Cain const std::string& path = subtree[0].first; 254637bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 254737bbf98cSChris Cain if (service.empty()) 254837bbf98cSChris Cain { 2549002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 255037bbf98cSChris Cain messages::internalError(aResp->res); 255137bbf98cSChris Cain return; 255237bbf98cSChris Cain } 255337bbf98cSChris Cain 255437bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 255537bbf98cSChris Cain // need to be updated 255637bbf98cSChris Cain 255737bbf98cSChris Cain if (ipsEnable) 255837bbf98cSChris Cain { 255937bbf98cSChris Cain crow::connections::systemBus->async_method_call( 25608a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 25618a592810SEd Tanous if (ec2) 256237bbf98cSChris Cain { 25638a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 256437bbf98cSChris Cain messages::internalError(aResp->res); 256537bbf98cSChris Cain return; 256637bbf98cSChris Cain } 256737bbf98cSChris Cain }, 256837bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 2569002d39b4SEd Tanous "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 2570002d39b4SEd Tanous dbus::utility::DbusVariantType(*ipsEnable)); 257137bbf98cSChris Cain } 257237bbf98cSChris Cain if (ipsEnterUtil) 257337bbf98cSChris Cain { 257437bbf98cSChris Cain crow::connections::systemBus->async_method_call( 25758a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 25768a592810SEd Tanous if (ec2) 257737bbf98cSChris Cain { 25788a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 257937bbf98cSChris Cain messages::internalError(aResp->res); 258037bbf98cSChris Cain return; 258137bbf98cSChris Cain } 258237bbf98cSChris Cain }, 258337bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 258437bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 258537bbf98cSChris Cain "EnterUtilizationPercent", 2586168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsEnterUtil)); 258737bbf98cSChris Cain } 258837bbf98cSChris Cain if (ipsEnterTime) 258937bbf98cSChris Cain { 259037bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 259137bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 259237bbf98cSChris Cain crow::connections::systemBus->async_method_call( 25938a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 25948a592810SEd Tanous if (ec2) 259537bbf98cSChris Cain { 25968a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 259737bbf98cSChris Cain messages::internalError(aResp->res); 259837bbf98cSChris Cain return; 259937bbf98cSChris Cain } 260037bbf98cSChris Cain }, 260137bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 260237bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2603168e20c1SEd Tanous "EnterDwellTime", 2604168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 260537bbf98cSChris Cain } 260637bbf98cSChris Cain if (ipsExitUtil) 260737bbf98cSChris Cain { 260837bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26098a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 26108a592810SEd Tanous if (ec2) 261137bbf98cSChris Cain { 26128a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 261337bbf98cSChris Cain messages::internalError(aResp->res); 261437bbf98cSChris Cain return; 261537bbf98cSChris Cain } 261637bbf98cSChris Cain }, 261737bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 261837bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 261937bbf98cSChris Cain "ExitUtilizationPercent", 2620168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsExitUtil)); 262137bbf98cSChris Cain } 262237bbf98cSChris Cain if (ipsExitTime) 262337bbf98cSChris Cain { 262437bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 262537bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 262637bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26278a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 26288a592810SEd Tanous if (ec2) 262937bbf98cSChris Cain { 26308a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 263137bbf98cSChris Cain messages::internalError(aResp->res); 263237bbf98cSChris Cain return; 263337bbf98cSChris Cain } 263437bbf98cSChris Cain }, 263537bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 263637bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2637168e20c1SEd Tanous "ExitDwellTime", 2638168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 263937bbf98cSChris Cain } 2640e99073f5SGeorge Liu }); 264137bbf98cSChris Cain 264237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 264337bbf98cSChris Cain } 264437bbf98cSChris Cain 2645dd60b9edSEd Tanous inline void handleComputerSystemHead( 2646dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2647dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2648dd60b9edSEd Tanous { 2649dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2650dd60b9edSEd Tanous { 2651dd60b9edSEd Tanous return; 2652dd60b9edSEd Tanous } 2653dd60b9edSEd Tanous asyncResp->res.addHeader( 2654dd60b9edSEd Tanous boost::beast::http::field::link, 2655dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2656dd60b9edSEd Tanous } 2657dd60b9edSEd Tanous 2658c45f0082SYong Li /** 2659c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 2660c5b2abe0SLewanczyk, Dawid * Schema 2661c5b2abe0SLewanczyk, Dawid */ 26627e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app) 26631abe55efSEd Tanous { 26647e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2665dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 2666dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 2667dd60b9edSEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 2668dd60b9edSEd Tanous 2669dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2670ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 26717e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 2672f4c99e70SEd Tanous [&app](const crow::Request& req, 26737e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 26743ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2675f4c99e70SEd Tanous { 2676f4c99e70SEd Tanous return; 2677f4c99e70SEd Tanous } 2678dd60b9edSEd Tanous 2679dd60b9edSEd Tanous asyncResp->res.addHeader( 2680dd60b9edSEd Tanous boost::beast::http::field::link, 2681dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 26828d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 26830f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 26848d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 26858d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2686462023adSSunitha Harish 26871e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2688002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 26891e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2690002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 26918a592810SEd Tanous [asyncResp](const boost::system::error_code ec2, 26921e1e598dSJonathan Doman const std::string& /*hostName*/) { 2693002d39b4SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 26942c70f800SEd Tanous ifaceArray = nlohmann::json::array(); 2695002d39b4SEd Tanous auto& count = asyncResp->res.jsonValue["Members@odata.count"]; 26961476687dSEd Tanous 26971476687dSEd Tanous nlohmann::json::object_t system; 26981476687dSEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 26991476687dSEd Tanous ifaceArray.push_back(std::move(system)); 270094bda602STim Lee count = ifaceArray.size(); 27018a592810SEd Tanous if (!ec2) 2702462023adSSunitha Harish { 2703462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 27041476687dSEd Tanous nlohmann::json::object_t hypervisor; 2705002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 27061476687dSEd Tanous ifaceArray.push_back(std::move(hypervisor)); 27072c70f800SEd Tanous count = ifaceArray.size(); 2708cb13a392SEd Tanous } 27091e1e598dSJonathan Doman }); 27107e860f15SJohn Edward Broadbent }); 2711c5b2abe0SLewanczyk, Dawid } 27127e860f15SJohn Edward Broadbent 27137e860f15SJohn Edward Broadbent /** 27147e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 27157e860f15SJohn Edward Broadbent */ 27164f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 27177e860f15SJohn Edward Broadbent { 27187e860f15SJohn Edward Broadbent constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 27197e860f15SJohn Edward Broadbent constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 27207e860f15SJohn Edward Broadbent constexpr char const* interfaceName = 27217e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 27227e860f15SJohn Edward Broadbent constexpr char const* method = "NMI"; 27237e860f15SJohn Edward Broadbent 27247e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 27257e860f15SJohn Edward Broadbent [asyncResp](const boost::system::error_code ec) { 27267e860f15SJohn Edward Broadbent if (ec) 27277e860f15SJohn Edward Broadbent { 27287e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 27297e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 27307e860f15SJohn Edward Broadbent return; 27317e860f15SJohn Edward Broadbent } 27327e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 27337e860f15SJohn Edward Broadbent }, 27347e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 27357e860f15SJohn Edward Broadbent } 2736c5b2abe0SLewanczyk, Dawid 2737c5b2abe0SLewanczyk, Dawid /** 2738cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 2739cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 2740cc340dd9SEd Tanous */ 27417e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app) 2742cc340dd9SEd Tanous { 2743cc340dd9SEd Tanous /** 2744cc340dd9SEd Tanous * Function handles POST method request. 2745cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 2746cc340dd9SEd Tanous */ 27477e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 27487e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/") 2749ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 2750002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 2751002d39b4SEd Tanous [&app](const crow::Request& req, 27527e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 27533ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 275445ca1b86SEd Tanous { 275545ca1b86SEd Tanous return; 275645ca1b86SEd Tanous } 27579712f8acSEd Tanous std::string resetType; 275815ed6780SWilly Tu if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", 27597e860f15SJohn Edward Broadbent resetType)) 2760cc340dd9SEd Tanous { 2761cc340dd9SEd Tanous return; 2762cc340dd9SEd Tanous } 2763cc340dd9SEd Tanous 2764d22c8396SJason M. Bills // Get the command and host vs. chassis 2765cc340dd9SEd Tanous std::string command; 2766543f4400SEd Tanous bool hostCommand = true; 2767d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2768cc340dd9SEd Tanous { 2769cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2770d22c8396SJason M. Bills hostCommand = true; 2771d22c8396SJason M. Bills } 2772d22c8396SJason M. Bills else if (resetType == "ForceOff") 2773d22c8396SJason M. Bills { 2774d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2775d22c8396SJason M. Bills hostCommand = false; 2776d22c8396SJason M. Bills } 2777d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2778d22c8396SJason M. Bills { 277986a0851aSJason M. Bills command = 278086a0851aSJason M. Bills "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 278186a0851aSJason M. Bills hostCommand = true; 2782cc340dd9SEd Tanous } 27839712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2784cc340dd9SEd Tanous { 2785cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2786d22c8396SJason M. Bills hostCommand = true; 2787cc340dd9SEd Tanous } 27889712f8acSEd Tanous else if (resetType == "GracefulRestart") 2789cc340dd9SEd Tanous { 27900fda0f12SGeorge Liu command = 27910fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2792d22c8396SJason M. Bills hostCommand = true; 2793d22c8396SJason M. Bills } 2794d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2795d22c8396SJason M. Bills { 279686a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 279786a0851aSJason M. Bills hostCommand = true; 2798cc340dd9SEd Tanous } 2799bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2800bfd5b826SLakshminarayana R. Kammath { 2801bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2802bfd5b826SLakshminarayana R. Kammath return; 2803bfd5b826SLakshminarayana R. Kammath } 2804cc340dd9SEd Tanous else 2805cc340dd9SEd Tanous { 28068d1b46d7Szhanghch05 messages::actionParameterUnknown(asyncResp->res, "Reset", 28078d1b46d7Szhanghch05 resetType); 2808cc340dd9SEd Tanous return; 2809cc340dd9SEd Tanous } 2810cc340dd9SEd Tanous 2811d22c8396SJason M. Bills if (hostCommand) 2812d22c8396SJason M. Bills { 2813cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 2814d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2815cc340dd9SEd Tanous if (ec) 2816cc340dd9SEd Tanous { 2817cc340dd9SEd Tanous BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 2818002d39b4SEd Tanous if (ec.value() == boost::asio::error::invalid_argument) 2819d22c8396SJason M. Bills { 2820d22c8396SJason M. Bills messages::actionParameterNotSupported( 2821d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2822d22c8396SJason M. Bills } 2823d22c8396SJason M. Bills else 2824d22c8396SJason M. Bills { 2825f12894f8SJason M. Bills messages::internalError(asyncResp->res); 2826d22c8396SJason M. Bills } 2827cc340dd9SEd Tanous return; 2828cc340dd9SEd Tanous } 2829f12894f8SJason M. Bills messages::success(asyncResp->res); 2830cc340dd9SEd Tanous }, 2831cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 2832cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 2833cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 28349712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 2835168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 2836cc340dd9SEd Tanous } 2837d22c8396SJason M. Bills else 2838d22c8396SJason M. Bills { 2839d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 2840d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2841d22c8396SJason M. Bills if (ec) 2842d22c8396SJason M. Bills { 2843d22c8396SJason M. Bills BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 2844002d39b4SEd Tanous if (ec.value() == boost::asio::error::invalid_argument) 2845d22c8396SJason M. Bills { 2846d22c8396SJason M. Bills messages::actionParameterNotSupported( 2847d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2848d22c8396SJason M. Bills } 2849d22c8396SJason M. Bills else 2850d22c8396SJason M. Bills { 2851d22c8396SJason M. Bills messages::internalError(asyncResp->res); 2852d22c8396SJason M. Bills } 2853d22c8396SJason M. Bills return; 2854d22c8396SJason M. Bills } 2855d22c8396SJason M. Bills messages::success(asyncResp->res); 2856d22c8396SJason M. Bills }, 2857d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 2858d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 2859d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 2860002d39b4SEd Tanous "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 2861168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 2862d22c8396SJason M. Bills } 28637e860f15SJohn Edward Broadbent }); 2864d22c8396SJason M. Bills } 2865cc340dd9SEd Tanous 286638c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead( 2867dd60b9edSEd Tanous App& app, const crow::Request& req, 2868dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2869dd60b9edSEd Tanous { 2870dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2871dd60b9edSEd Tanous { 2872dd60b9edSEd Tanous return; 2873dd60b9edSEd Tanous } 2874dd60b9edSEd Tanous 2875dd60b9edSEd Tanous asyncResp->res.addHeader( 2876dd60b9edSEd Tanous boost::beast::http::field::link, 2877dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2878dd60b9edSEd Tanous } 2879dd60b9edSEd Tanous 2880cc340dd9SEd Tanous /** 28816617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 2882c5b2abe0SLewanczyk, Dawid */ 28837e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app) 28841abe55efSEd Tanous { 2885c5b2abe0SLewanczyk, Dawid 2886dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 2887dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystem) 2888dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 2889dd60b9edSEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 2890c5b2abe0SLewanczyk, Dawid /** 2891c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 2892c5b2abe0SLewanczyk, Dawid */ 289322d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 2894ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystem) 2895002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 2896002d39b4SEd Tanous [&app](const crow::Request& req, 289722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 289822d268cbSEd Tanous const std::string& systemName) { 28993ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 290045ca1b86SEd Tanous { 290145ca1b86SEd Tanous return; 290245ca1b86SEd Tanous } 290322d268cbSEd Tanous if (systemName != "system") 290422d268cbSEd Tanous { 290522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 290622d268cbSEd Tanous systemName); 290722d268cbSEd Tanous return; 290822d268cbSEd Tanous } 2909dd60b9edSEd Tanous asyncResp->res.addHeader( 2910dd60b9edSEd Tanous boost::beast::http::field::link, 2911dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 29128d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 291337bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 29148d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 29158d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 29168d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 29178d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 29188d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 29198d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 29208d1b46d7Szhanghch05 "Disabled"; 29218d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 29228d1b46d7Szhanghch05 uint64_t(0); 29238d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 29248d1b46d7Szhanghch05 "Disabled"; 2925002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 292604a258f4SEd Tanous 29271476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 29281476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 29291476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 29301476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 29311476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 29321476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 29333179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 29343179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 2935029573d4SEd Tanous 2936002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 29371476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 29381476687dSEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] 29391476687dSEd Tanous ["@Redfish.ActionInfo"] = 29401476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 2941c5b2abe0SLewanczyk, Dawid 29421476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 29431476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 29441476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 29451476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 2946c4bf6374SJason M. Bills 29471476687dSEd Tanous nlohmann::json::array_t managedBy; 29481476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 29491476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 2950002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 29511476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 29521476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 29530e8ac5e7SGunnar Mills 29540e8ac5e7SGunnar Mills // Fill in SerialConsole info 2955002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 2956002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = 2957002d39b4SEd Tanous true; 29581476687dSEd Tanous 29590e8ac5e7SGunnar Mills // TODO (Gunnar): Should look for obmc-console-ssh@2200.service 29601476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = 29611476687dSEd Tanous true; 29621476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 29631476687dSEd Tanous asyncResp->res 29641476687dSEd Tanous .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 29651476687dSEd Tanous "Press ~. to exit console"; 29660e8ac5e7SGunnar Mills 29670e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 29680e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 2969002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 2970002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 2971002d39b4SEd Tanous 4; 2972613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 2973613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 29741476687dSEd Tanous 29750e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 29767a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 2977b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 29782ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 2979e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 2980e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 2981b49ac873SJames Feist 2982b49ac873SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 29837a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 29847a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 29857a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 2986914e2d5dSEd Tanous const std::vector<std::string>& resp) { 2987b49ac873SJames Feist if (ec) 2988b49ac873SJames Feist { 2989b49ac873SJames Feist // no inventory 2990b49ac873SJames Feist return; 2991b49ac873SJames Feist } 2992b49ac873SJames Feist 2993914e2d5dSEd Tanous health->inventory = resp; 29947a1dbc48SGeorge Liu }); 2995b49ac873SJames Feist 2996b49ac873SJames Feist health->populate(); 2997b49ac873SJames Feist 2998002d39b4SEd Tanous getMainChassisId(asyncResp, 2999002d39b4SEd Tanous [](const std::string& chassisId, 30008d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3001b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3002b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3003*eddfc437SWilly Tu chassis["@odata.id"] = crow::utility::urlFromPieces( 3004*eddfc437SWilly Tu "redfish", "v1", "Chassis", chassisId); 3005002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3006c5d03ff4SJennifer Lee }); 3007a3002228SAppaRao Puli 30089f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 30099f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3010a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 30115bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 30126c34de48SEd Tanous getHostState(asyncResp); 3013491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3014978b8803SAndrew Geissler getBootProgress(asyncResp); 3015b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3016adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "PCIeDevices"); 301751709ffdSYong Li getHostWatchdogTimer(asyncResp); 3018c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 30196bd5a8d2SGunnar Mills getAutomaticRetry(asyncResp); 3020c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3021a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3022a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3023a6349918SAppaRao Puli #endif 30241981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 30253a2d0424SChris Cain getPowerMode(asyncResp); 302637bbf98cSChris Cain getIdlePowerSaver(asyncResp); 30277e860f15SJohn Edward Broadbent }); 3028550a6bf8SJiaqing Zhao 302922d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3030ed398213SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 30317e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 303245ca1b86SEd Tanous [&app](const crow::Request& req, 303322d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 303422d268cbSEd Tanous const std::string& systemName) { 30353ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 303645ca1b86SEd Tanous { 303745ca1b86SEd Tanous return; 303845ca1b86SEd Tanous } 303922d268cbSEd Tanous if (systemName != "system") 304022d268cbSEd Tanous { 304122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 304222d268cbSEd Tanous systemName); 304322d268cbSEd Tanous return; 304422d268cbSEd Tanous } 304522d268cbSEd Tanous 3046dd60b9edSEd Tanous asyncResp->res.addHeader( 3047dd60b9edSEd Tanous boost::beast::http::field::link, 3048dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3049dd60b9edSEd Tanous 30509f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3051cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 305298e386ecSGunnar Mills std::optional<std::string> assetTag; 3053c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 30543a2d0424SChris Cain std::optional<std::string> powerMode; 3055550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3056550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3057550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3058550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3059550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3060550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3061550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 3062550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3063550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3064550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3065550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3066550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3067550a6bf8SJiaqing Zhao 3068550a6bf8SJiaqing Zhao // clang-format off 306915ed6780SWilly Tu if (!json_util::readJsonPatch( 3070550a6bf8SJiaqing Zhao req, asyncResp->res, 3071550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 30727e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3073550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3074550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3075550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3076550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3077550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3078550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3079550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3080550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3081550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3082550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 3083550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3084550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3085550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3086550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3087550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 30886617338dSEd Tanous { 30896617338dSEd Tanous return; 30906617338dSEd Tanous } 3091550a6bf8SJiaqing Zhao // clang-format on 3092491d8ee7SSantosh Puranik 30938d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3094c45f0082SYong Li 309598e386ecSGunnar Mills if (assetTag) 309698e386ecSGunnar Mills { 309798e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 309898e386ecSGunnar Mills } 309998e386ecSGunnar Mills 3100550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3101c45f0082SYong Li { 3102f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3103c45f0082SYong Li } 3104c45f0082SYong Li 3105cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 310669f35306SGunnar Mills { 3107002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3108491d8ee7SSantosh Puranik } 3109550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 311069f35306SGunnar Mills { 3111550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 311269f35306SGunnar Mills } 3113ac7e1e0bSAli Ahmed 3114550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3115ac7e1e0bSAli Ahmed { 3116550a6bf8SJiaqing Zhao setTrustedModuleRequiredToBoot(asyncResp, 3117550a6bf8SJiaqing Zhao *bootTrustedModuleRequired); 311869f35306SGunnar Mills } 3119265c1602SJohnathan Mantey 31209f8bfa7cSGunnar Mills if (locationIndicatorActive) 31219f8bfa7cSGunnar Mills { 3122002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 31239f8bfa7cSGunnar Mills } 31249f8bfa7cSGunnar Mills 31257e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 31267e860f15SJohn Edward Broadbent // passed 31279712f8acSEd Tanous if (indicatorLed) 31286617338dSEd Tanous { 3129f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3130002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3131d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3132d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 31336617338dSEd Tanous } 3134c6a620f2SGeorge Liu 3135c6a620f2SGeorge Liu if (powerRestorePolicy) 3136c6a620f2SGeorge Liu { 31374e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3138c6a620f2SGeorge Liu } 31393a2d0424SChris Cain 31403a2d0424SChris Cain if (powerMode) 31413a2d0424SChris Cain { 31423a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 31433a2d0424SChris Cain } 314437bbf98cSChris Cain 3145550a6bf8SJiaqing Zhao if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || 3146550a6bf8SJiaqing Zhao ipsExitTime) 314737bbf98cSChris Cain { 3148002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3149002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 315037bbf98cSChris Cain } 31517e860f15SJohn Edward Broadbent }); 3152c5b2abe0SLewanczyk, Dawid } 31531cb1a9e6SAppaRao Puli 315438c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3155dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 3156dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3157dd60b9edSEd Tanous { 3158dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3159dd60b9edSEd Tanous { 3160dd60b9edSEd Tanous return; 3161dd60b9edSEd Tanous } 3162dd60b9edSEd Tanous asyncResp->res.addHeader( 3163dd60b9edSEd Tanous boost::beast::http::field::link, 3164dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3165dd60b9edSEd Tanous } 3166dd60b9edSEd Tanous 31671cb1a9e6SAppaRao Puli /** 31681cb1a9e6SAppaRao Puli * SystemResetActionInfo derived class for delivering Computer Systems 31691cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 31701cb1a9e6SAppaRao Puli */ 31717e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app) 31721cb1a9e6SAppaRao Puli { 3173dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/") 3174dd60b9edSEd Tanous .privileges(redfish::privileges::headActionInfo) 3175dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3176dd60b9edSEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 31771cb1a9e6SAppaRao Puli /** 31781cb1a9e6SAppaRao Puli * Functions triggers appropriate requests on DBus 31791cb1a9e6SAppaRao Puli */ 318022d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3181ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 31827e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 318345ca1b86SEd Tanous [&app](const crow::Request& req, 318422d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 318522d268cbSEd Tanous const std::string& systemName) { 31863ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 318745ca1b86SEd Tanous { 318845ca1b86SEd Tanous return; 318945ca1b86SEd Tanous } 319022d268cbSEd Tanous if (systemName != "system") 319122d268cbSEd Tanous { 319222d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 319322d268cbSEd Tanous systemName); 319422d268cbSEd Tanous return; 319522d268cbSEd Tanous } 319622d268cbSEd Tanous 3197dd60b9edSEd Tanous asyncResp->res.addHeader( 3198dd60b9edSEd Tanous boost::beast::http::field::link, 3199dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 32001476687dSEd Tanous 32011476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 32021476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 32031476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 32041476687dSEd Tanous "#ActionInfo.v1_1_2.ActionInfo"; 32051476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 32061476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 32073215e700SNan Zhou 32083215e700SNan Zhou nlohmann::json::array_t parameters; 32093215e700SNan Zhou nlohmann::json::object_t parameter; 32103215e700SNan Zhou 32113215e700SNan Zhou parameter["Name"] = "ResetType"; 32123215e700SNan Zhou parameter["Required"] = true; 32133215e700SNan Zhou parameter["DataType"] = "String"; 32143215e700SNan Zhou nlohmann::json::array_t allowableValues; 32153215e700SNan Zhou allowableValues.emplace_back("On"); 32163215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 32173215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 32183215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 32193215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 32203215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 32213215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 32223215e700SNan Zhou allowableValues.emplace_back("Nmi"); 32233215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 32243215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 32253215e700SNan Zhou 32263215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 32277e860f15SJohn Edward Broadbent }); 32281cb1a9e6SAppaRao Puli } 3229c5b2abe0SLewanczyk, Dawid } // namespace redfish 3230