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 18*3ccb3adbSEd 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" 26*3ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 27*3ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 28*3ccb3adbSEd Tanous #include "utils/json_utils.hpp" 29*3ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 302b82937eSEd Tanous #include "utils/time_utils.hpp" 31c5d03ff4SJennifer Lee 329712f8acSEd Tanous #include <boost/container/flat_map.hpp> 331e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 34bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 351214b7e7SGunnar Mills 367a1dbc48SGeorge Liu #include <array> 377a1dbc48SGeorge Liu #include <string_view> 38abf2add6SEd Tanous #include <variant> 39c5b2abe0SLewanczyk, Dawid 401abe55efSEd Tanous namespace redfish 411abe55efSEd Tanous { 42c5b2abe0SLewanczyk, Dawid 439d3ae10eSAlpana Kumari /** 449d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 459d3ae10eSAlpana Kumari * 469d3ae10eSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 479d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 489d3ae10eSAlpana Kumari * 499d3ae10eSAlpana Kumari * @return None. 509d3ae10eSAlpana Kumari */ 518d1b46d7Szhanghch05 inline void 528d1b46d7Szhanghch05 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 531e1e598dSJonathan Doman bool isDimmFunctional) 549d3ae10eSAlpana Kumari { 551e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional; 569d3ae10eSAlpana Kumari 579d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 589d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 599d3ae10eSAlpana Kumari // ENABLED. 6002cad96eSEd Tanous const nlohmann::json& prevMemSummary = 619d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 629d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 639d3ae10eSAlpana Kumari { 64e05aec50SEd Tanous if (isDimmFunctional) 659d3ae10eSAlpana Kumari { 669d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 679d3ae10eSAlpana Kumari "Enabled"; 689d3ae10eSAlpana Kumari } 699d3ae10eSAlpana Kumari } 709d3ae10eSAlpana Kumari } 719d3ae10eSAlpana Kumari 7257e8c9beSAlpana Kumari /* 7357e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 7457e8c9beSAlpana Kumari * 7557e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 7657e8c9beSAlpana Kumari * @param[in] cpuPresenceState CPU present or not 7757e8c9beSAlpana Kumari * 7857e8c9beSAlpana Kumari * @return None. 7957e8c9beSAlpana Kumari */ 801e1e598dSJonathan Doman inline void 811e1e598dSJonathan Doman modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 821e1e598dSJonathan Doman bool isCpuPresent) 8357e8c9beSAlpana Kumari { 841e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent; 8557e8c9beSAlpana Kumari 8655f79e6fSEd Tanous if (isCpuPresent) 8757e8c9beSAlpana Kumari { 88b4b9595aSJames Feist nlohmann::json& procCount = 89b4b9595aSJames Feist aResp->res.jsonValue["ProcessorSummary"]["Count"]; 9055f79e6fSEd Tanous auto* procCountPtr = 91b4b9595aSJames Feist procCount.get_ptr<nlohmann::json::number_integer_t*>(); 92b4b9595aSJames Feist if (procCountPtr != nullptr) 93b4b9595aSJames Feist { 94b4b9595aSJames Feist // shouldn't be possible to be nullptr 95b4b9595aSJames Feist *procCountPtr += 1; 9657e8c9beSAlpana Kumari } 97b4b9595aSJames Feist } 9857e8c9beSAlpana Kumari } 9957e8c9beSAlpana Kumari 10057e8c9beSAlpana Kumari /* 10157e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 10257e8c9beSAlpana Kumari * CPU Functional State 10357e8c9beSAlpana Kumari * 10457e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 10557e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 10657e8c9beSAlpana Kumari * 10757e8c9beSAlpana Kumari * @return None. 10857e8c9beSAlpana Kumari */ 1091e1e598dSJonathan Doman inline void 1101e1e598dSJonathan Doman modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1111e1e598dSJonathan Doman bool isCpuFunctional) 11257e8c9beSAlpana Kumari { 1131e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional; 11457e8c9beSAlpana Kumari 11502cad96eSEd Tanous const nlohmann::json& prevProcState = 11657e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 11757e8c9beSAlpana Kumari 11857e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 11957e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 12057e8c9beSAlpana Kumari // Functional. 12157e8c9beSAlpana Kumari if (prevProcState == "Disabled") 12257e8c9beSAlpana Kumari { 123e05aec50SEd Tanous if (isCpuFunctional) 12457e8c9beSAlpana Kumari { 12557e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 12657e8c9beSAlpana Kumari "Enabled"; 12757e8c9beSAlpana Kumari } 12857e8c9beSAlpana Kumari } 12957e8c9beSAlpana Kumari } 13057e8c9beSAlpana Kumari 131382d6475SAli Ahmed inline void getProcessorProperties( 132382d6475SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, 133382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 134382d6475SAli Ahmed properties) 13503fbed92SAli Ahmed { 13603fbed92SAli Ahmed 13703fbed92SAli Ahmed BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties."; 13803fbed92SAli Ahmed 13903fbed92SAli Ahmed // TODO: Get Model 14003fbed92SAli Ahmed 141bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 14203fbed92SAli Ahmed 143bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 144bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 14503fbed92SAli Ahmed 146bc1d29deSKrzysztof Grobelny if (!success) 14703fbed92SAli Ahmed { 14803fbed92SAli Ahmed messages::internalError(aResp->res); 14903fbed92SAli Ahmed return; 15003fbed92SAli Ahmed } 15103fbed92SAli Ahmed 152bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 15303fbed92SAli Ahmed { 154bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 155bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 156bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 157bc1d29deSKrzysztof Grobelny 158bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 159bc1d29deSKrzysztof Grobelny { 160bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 16103fbed92SAli Ahmed } 16203fbed92SAli Ahmed else 16303fbed92SAli Ahmed { 164bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 16503fbed92SAli Ahmed } 16603fbed92SAli Ahmed } 16703fbed92SAli Ahmed } 16803fbed92SAli Ahmed 16903fbed92SAli Ahmed /* 17003fbed92SAli Ahmed * @brief Get ProcessorSummary fields 17103fbed92SAli Ahmed * 17203fbed92SAli Ahmed * @param[in] aResp Shared pointer for completing asynchronous calls 17303fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 17403fbed92SAli Ahmed * @param[in] path dbus path for Cpu 17503fbed92SAli Ahmed * 17603fbed92SAli Ahmed * @return None. 17703fbed92SAli Ahmed */ 17803fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 17903fbed92SAli Ahmed const std::string& service, 18003fbed92SAli Ahmed const std::string& path) 18103fbed92SAli Ahmed { 18203fbed92SAli Ahmed 183382d6475SAli Ahmed auto getCpuPresenceState = [aResp](const boost::system::error_code ec3, 184382d6475SAli Ahmed const bool cpuPresenceCheck) { 185382d6475SAli Ahmed if (ec3) 186382d6475SAli Ahmed { 187382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 188382d6475SAli Ahmed return; 189382d6475SAli Ahmed } 190382d6475SAli Ahmed modifyCpuPresenceState(aResp, cpuPresenceCheck); 191382d6475SAli Ahmed }; 192382d6475SAli Ahmed 193382d6475SAli Ahmed auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3, 194382d6475SAli Ahmed const bool cpuFunctionalCheck) { 195382d6475SAli Ahmed if (ec3) 196382d6475SAli Ahmed { 197382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 198382d6475SAli Ahmed return; 199382d6475SAli Ahmed } 200382d6475SAli Ahmed modifyCpuFunctionalState(aResp, cpuFunctionalCheck); 201382d6475SAli Ahmed }; 202382d6475SAli Ahmed 203382d6475SAli Ahmed // Get the Presence of CPU 204382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 205382d6475SAli Ahmed *crow::connections::systemBus, service, path, 206382d6475SAli Ahmed "xyz.openbmc_project.Inventory.Item", "Present", 207382d6475SAli Ahmed std::move(getCpuPresenceState)); 208382d6475SAli Ahmed 209382d6475SAli Ahmed // Get the Functional State 210382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 211382d6475SAli Ahmed *crow::connections::systemBus, service, path, 212382d6475SAli Ahmed "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional", 213382d6475SAli Ahmed std::move(getCpuFunctionalState)); 214382d6475SAli Ahmed 215bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 216bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 217bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 21803fbed92SAli Ahmed [aResp, service, 21903fbed92SAli Ahmed path](const boost::system::error_code ec2, 220b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 22103fbed92SAli Ahmed if (ec2) 22203fbed92SAli Ahmed { 22303fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 22403fbed92SAli Ahmed messages::internalError(aResp->res); 22503fbed92SAli Ahmed return; 22603fbed92SAli Ahmed } 227382d6475SAli Ahmed getProcessorProperties(aResp, properties); 228bc1d29deSKrzysztof Grobelny }); 22903fbed92SAli Ahmed } 23003fbed92SAli Ahmed 23157e8c9beSAlpana Kumari /* 232c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 233c5b2abe0SLewanczyk, Dawid * 234c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 2358f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 236c5b2abe0SLewanczyk, Dawid * 237c5b2abe0SLewanczyk, Dawid * @return None. 238c5b2abe0SLewanczyk, Dawid */ 239b5a76932SEd Tanous inline void 2408d1b46d7Szhanghch05 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 241b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 2421abe55efSEd Tanous { 24355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 2449d3ae10eSAlpana Kumari 24555c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 246b9d36b47SEd Tanous [aResp, 247b9d36b47SEd Tanous systemHealth](const boost::system::error_code ec, 248b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 2491abe55efSEd Tanous if (ec) 2501abe55efSEd Tanous { 25155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 252f12894f8SJason M. Bills messages::internalError(aResp->res); 253c5b2abe0SLewanczyk, Dawid return; 254c5b2abe0SLewanczyk, Dawid } 255c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 256002d39b4SEd Tanous for (const std::pair< 257002d39b4SEd Tanous std::string, 258002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 2591214b7e7SGunnar Mills object : subtree) 2601abe55efSEd Tanous { 261c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 26255c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 263002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 2641214b7e7SGunnar Mills connectionNames = object.second; 26526f6976fSEd Tanous if (connectionNames.empty()) 2661abe55efSEd Tanous { 267c5b2abe0SLewanczyk, Dawid continue; 268c5b2abe0SLewanczyk, Dawid } 269029573d4SEd Tanous 2705bc2dc8eSJames Feist auto memoryHealth = std::make_shared<HealthPopulate>( 271dfababfcSNan Zhou aResp, "/MemorySummary/Status"_json_pointer); 2725bc2dc8eSJames Feist 2735bc2dc8eSJames Feist auto cpuHealth = std::make_shared<HealthPopulate>( 274dfababfcSNan Zhou aResp, "/ProcessorSummary/Status"_json_pointer); 2755bc2dc8eSJames Feist 2765bc2dc8eSJames Feist systemHealth->children.emplace_back(memoryHealth); 2775bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 2785bc2dc8eSJames Feist 2796c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 2806c34de48SEd Tanous // BiosVer 28104a258f4SEd Tanous for (const auto& connection : connectionNames) 2821abe55efSEd Tanous { 28304a258f4SEd Tanous for (const auto& interfaceName : connection.second) 2841abe55efSEd Tanous { 28504a258f4SEd Tanous if (interfaceName == 28604a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 2871abe55efSEd Tanous { 2881abe55efSEd Tanous BMCWEB_LOG_DEBUG 28904a258f4SEd Tanous << "Found Dimm, now get its properties."; 2909d3ae10eSAlpana Kumari 291bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 292bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 293bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Inventory.Item.Dimm", 2949d3ae10eSAlpana Kumari [aResp, service{connection.first}, 295f23b7296SEd Tanous path](const boost::system::error_code ec2, 296b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 2971214b7e7SGunnar Mills properties) { 298cb13a392SEd Tanous if (ec2) 2991abe55efSEd Tanous { 300002d39b4SEd Tanous BMCWEB_LOG_ERROR << "DBUS response error " 301002d39b4SEd Tanous << ec2; 302f12894f8SJason M. Bills messages::internalError(aResp->res); 303c5b2abe0SLewanczyk, Dawid return; 304c5b2abe0SLewanczyk, Dawid } 305002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 306c5b2abe0SLewanczyk, Dawid << " Dimm properties."; 3079d3ae10eSAlpana Kumari 308bc1d29deSKrzysztof Grobelny if (properties.empty()) 3099d3ae10eSAlpana Kumari { 3101e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 311002d39b4SEd Tanous *crow::connections::systemBus, service, 312002d39b4SEd Tanous path, 3131e1e598dSJonathan Doman "xyz.openbmc_project.State." 3141e1e598dSJonathan Doman "Decorator.OperationalStatus", 3151e1e598dSJonathan Doman "Functional", 316002d39b4SEd Tanous [aResp](const boost::system::error_code ec3, 3171e1e598dSJonathan Doman bool dimmState) { 318cb13a392SEd Tanous if (ec3) 3199d3ae10eSAlpana Kumari { 3209d3ae10eSAlpana Kumari BMCWEB_LOG_ERROR 321002d39b4SEd Tanous << "DBUS response error " << ec3; 3229d3ae10eSAlpana Kumari return; 3239d3ae10eSAlpana Kumari } 324002d39b4SEd Tanous updateDimmProperties(aResp, dimmState); 3251e1e598dSJonathan Doman }); 326bc1d29deSKrzysztof Grobelny return; 3279d3ae10eSAlpana Kumari } 328bc1d29deSKrzysztof Grobelny 329bc1d29deSKrzysztof Grobelny const uint32_t* memorySizeInKB = nullptr; 330bc1d29deSKrzysztof Grobelny 331bc1d29deSKrzysztof Grobelny const bool success = 332bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 333bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 334bc1d29deSKrzysztof Grobelny properties, "MemorySizeInKB", 335bc1d29deSKrzysztof Grobelny memorySizeInKB); 336bc1d29deSKrzysztof Grobelny 337bc1d29deSKrzysztof Grobelny if (!success) 338bc1d29deSKrzysztof Grobelny { 339bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 340bc1d29deSKrzysztof Grobelny return; 341bc1d29deSKrzysztof Grobelny } 342bc1d29deSKrzysztof Grobelny 343bc1d29deSKrzysztof Grobelny if (memorySizeInKB != nullptr) 344bc1d29deSKrzysztof Grobelny { 345bc1d29deSKrzysztof Grobelny nlohmann::json& totalMemory = 346bc1d29deSKrzysztof Grobelny aResp->res 347bc1d29deSKrzysztof Grobelny .jsonValue["MemorySummary"] 348bc1d29deSKrzysztof Grobelny ["TotalSystemMemoryGiB"]; 349bc1d29deSKrzysztof Grobelny const uint64_t* preValue = 350bc1d29deSKrzysztof Grobelny totalMemory.get_ptr<const uint64_t*>(); 351bc1d29deSKrzysztof Grobelny if (preValue == nullptr) 352bc1d29deSKrzysztof Grobelny { 353bc1d29deSKrzysztof Grobelny aResp->res 354bc1d29deSKrzysztof Grobelny .jsonValue["MemorySummary"] 355bc1d29deSKrzysztof Grobelny ["TotalSystemMemoryGiB"] = 356bc1d29deSKrzysztof Grobelny *memorySizeInKB / (1024 * 1024); 357bc1d29deSKrzysztof Grobelny } 358bc1d29deSKrzysztof Grobelny else 359bc1d29deSKrzysztof Grobelny { 360bc1d29deSKrzysztof Grobelny aResp->res 361bc1d29deSKrzysztof Grobelny .jsonValue["MemorySummary"] 362bc1d29deSKrzysztof Grobelny ["TotalSystemMemoryGiB"] = 363bc1d29deSKrzysztof Grobelny *memorySizeInKB / (1024 * 1024) + 364bc1d29deSKrzysztof Grobelny *preValue; 365bc1d29deSKrzysztof Grobelny } 366bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["MemorySummary"]["Status"] 367bc1d29deSKrzysztof Grobelny ["State"] = "Enabled"; 368bc1d29deSKrzysztof Grobelny } 369bc1d29deSKrzysztof Grobelny }); 3705bc2dc8eSJames Feist 3715bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 3721abe55efSEd Tanous } 37304a258f4SEd Tanous else if (interfaceName == 37404a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 3751abe55efSEd Tanous { 3761abe55efSEd Tanous BMCWEB_LOG_DEBUG 37704a258f4SEd Tanous << "Found Cpu, now get its properties."; 37857e8c9beSAlpana Kumari 37903fbed92SAli Ahmed getProcessorSummary(aResp, connection.first, path); 3805bc2dc8eSJames Feist 3815bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 3821abe55efSEd Tanous } 383002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 3841abe55efSEd Tanous { 3851abe55efSEd Tanous BMCWEB_LOG_DEBUG 38604a258f4SEd Tanous << "Found UUID, now get its properties."; 387bc1d29deSKrzysztof Grobelny 388bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 389bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 390bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Common.UUID", 391168e20c1SEd Tanous [aResp](const boost::system::error_code ec3, 392b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 3931214b7e7SGunnar Mills properties) { 394cb13a392SEd Tanous if (ec3) 3951abe55efSEd Tanous { 396002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " 397002d39b4SEd Tanous << ec3; 398f12894f8SJason M. Bills messages::internalError(aResp->res); 399c5b2abe0SLewanczyk, Dawid return; 400c5b2abe0SLewanczyk, Dawid } 401002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 402c5b2abe0SLewanczyk, Dawid << " UUID properties."; 40304a258f4SEd Tanous 404bc1d29deSKrzysztof Grobelny const std::string* uUID = nullptr; 405bc1d29deSKrzysztof Grobelny 406bc1d29deSKrzysztof Grobelny const bool success = 407bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 408bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 409bc1d29deSKrzysztof Grobelny properties, "UUID", uUID); 410bc1d29deSKrzysztof Grobelny 411bc1d29deSKrzysztof Grobelny if (!success) 4121abe55efSEd Tanous { 413bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 414bc1d29deSKrzysztof Grobelny return; 415bc1d29deSKrzysztof Grobelny } 416bc1d29deSKrzysztof Grobelny 417bc1d29deSKrzysztof Grobelny if (uUID != nullptr) 418bc1d29deSKrzysztof Grobelny { 419bc1d29deSKrzysztof Grobelny std::string valueStr = *uUID; 42004a258f4SEd Tanous if (valueStr.size() == 32) 4211abe55efSEd Tanous { 422029573d4SEd Tanous valueStr.insert(8, 1, '-'); 423029573d4SEd Tanous valueStr.insert(13, 1, '-'); 424029573d4SEd Tanous valueStr.insert(18, 1, '-'); 425029573d4SEd Tanous valueStr.insert(23, 1, '-'); 42604a258f4SEd Tanous } 427bc1d29deSKrzysztof Grobelny BMCWEB_LOG_DEBUG << "UUID = " << valueStr; 428002d39b4SEd Tanous aResp->res.jsonValue["UUID"] = valueStr; 429c5b2abe0SLewanczyk, Dawid } 430bc1d29deSKrzysztof Grobelny }); 431c5b2abe0SLewanczyk, Dawid } 432029573d4SEd Tanous else if (interfaceName == 433029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4341abe55efSEd Tanous { 435bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 436bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 437bc1d29deSKrzysztof Grobelny path, 438bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 439168e20c1SEd Tanous [aResp](const boost::system::error_code ec2, 440b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4411214b7e7SGunnar Mills propertiesList) { 442cb13a392SEd Tanous if (ec2) 443029573d4SEd Tanous { 444e4a4b9a9SJames Feist // doesn't have to include this 445e4a4b9a9SJames Feist // interface 446029573d4SEd Tanous return; 447029573d4SEd Tanous } 448002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 449029573d4SEd Tanous << " properties for system"; 450bc1d29deSKrzysztof Grobelny 451bc1d29deSKrzysztof Grobelny const std::string* partNumber = nullptr; 452bc1d29deSKrzysztof Grobelny const std::string* serialNumber = nullptr; 453bc1d29deSKrzysztof Grobelny const std::string* manufacturer = nullptr; 454bc1d29deSKrzysztof Grobelny const std::string* model = nullptr; 455bc1d29deSKrzysztof Grobelny const std::string* subModel = nullptr; 456bc1d29deSKrzysztof Grobelny 457bc1d29deSKrzysztof Grobelny const bool success = 458bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 459bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 460bc1d29deSKrzysztof Grobelny propertiesList, "PartNumber", partNumber, 461bc1d29deSKrzysztof Grobelny "SerialNumber", serialNumber, 462bc1d29deSKrzysztof Grobelny "Manufacturer", manufacturer, "Model", 463bc1d29deSKrzysztof Grobelny model, "SubModel", subModel); 464bc1d29deSKrzysztof Grobelny 465bc1d29deSKrzysztof Grobelny if (!success) 466029573d4SEd Tanous { 467bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 468bc1d29deSKrzysztof Grobelny return; 469029573d4SEd Tanous } 470bc1d29deSKrzysztof Grobelny 471bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 472bc1d29deSKrzysztof Grobelny { 473bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["PartNumber"] = 474bc1d29deSKrzysztof Grobelny *partNumber; 475029573d4SEd Tanous } 476bc1d29deSKrzysztof Grobelny 477bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 478bc1d29deSKrzysztof Grobelny { 479bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SerialNumber"] = 480bc1d29deSKrzysztof Grobelny *serialNumber; 481bc1d29deSKrzysztof Grobelny } 482bc1d29deSKrzysztof Grobelny 483bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 484bc1d29deSKrzysztof Grobelny { 485bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Manufacturer"] = 486bc1d29deSKrzysztof Grobelny *manufacturer; 487bc1d29deSKrzysztof Grobelny } 488bc1d29deSKrzysztof Grobelny 489bc1d29deSKrzysztof Grobelny if (model != nullptr) 490bc1d29deSKrzysztof Grobelny { 491bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Model"] = *model; 492bc1d29deSKrzysztof Grobelny } 493bc1d29deSKrzysztof Grobelny 494bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 495bc1d29deSKrzysztof Grobelny { 496bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SubModel"] = *subModel; 497fc5afcf9Sbeccabroek } 498c1e236a6SGunnar Mills 499cb7e1e7bSAndrew Geissler // Grab the bios version 500eee0013eSWilly Tu sw_util::populateSoftwareInformation( 501eee0013eSWilly Tu aResp, sw_util::biosPurpose, "BiosVersion", 502002d39b4SEd Tanous false); 503bc1d29deSKrzysztof Grobelny }); 504e4a4b9a9SJames Feist 5051e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5061e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5071e1e598dSJonathan Doman path, 5081e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5091e1e598dSJonathan Doman "AssetTag", 5101e1e598dSJonathan Doman "AssetTag", 511168e20c1SEd Tanous [aResp](const boost::system::error_code ec2, 5121e1e598dSJonathan Doman const std::string& value) { 513cb13a392SEd Tanous if (ec2) 514e4a4b9a9SJames Feist { 515e4a4b9a9SJames Feist // doesn't have to include this 516e4a4b9a9SJames Feist // interface 517e4a4b9a9SJames Feist return; 518e4a4b9a9SJames Feist } 519e4a4b9a9SJames Feist 5201e1e598dSJonathan Doman aResp->res.jsonValue["AssetTag"] = value; 5211e1e598dSJonathan Doman }); 522029573d4SEd Tanous } 523029573d4SEd Tanous } 524bc1d29deSKrzysztof Grobelny break; 525029573d4SEd Tanous } 526c5b2abe0SLewanczyk, Dawid } 527c5b2abe0SLewanczyk, Dawid }, 528c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 529c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 530c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTree", 5316617338dSEd Tanous "/xyz/openbmc_project/inventory", int32_t(0), 5326617338dSEd Tanous std::array<const char*, 5>{ 5336617338dSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset", 5346617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu", 5356617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm", 5366617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.System", 5376617338dSEd Tanous "xyz.openbmc_project.Common.UUID", 5386617338dSEd Tanous }); 539c5b2abe0SLewanczyk, Dawid } 540c5b2abe0SLewanczyk, Dawid 541c5b2abe0SLewanczyk, Dawid /** 542c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 543c5b2abe0SLewanczyk, Dawid * 544c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 545c5b2abe0SLewanczyk, Dawid * 546c5b2abe0SLewanczyk, Dawid * @return None. 547c5b2abe0SLewanczyk, Dawid */ 5488d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 5491abe55efSEd Tanous { 55055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 5511e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5521e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 5531e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 5541e1e598dSJonathan Doman "CurrentHostState", 555c5d03ff4SJennifer Lee [aResp](const boost::system::error_code ec, 5561e1e598dSJonathan Doman const std::string& hostState) { 5571abe55efSEd Tanous if (ec) 5581abe55efSEd Tanous { 55922228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 56022228c28SAndrew Geissler { 56122228c28SAndrew Geissler // Service not available, no error, just don't return 56222228c28SAndrew Geissler // host state info 56322228c28SAndrew Geissler BMCWEB_LOG_DEBUG << "Service not available " << ec; 56422228c28SAndrew Geissler return; 56522228c28SAndrew Geissler } 56622228c28SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 567f12894f8SJason M. Bills messages::internalError(aResp->res); 568c5b2abe0SLewanczyk, Dawid return; 569c5b2abe0SLewanczyk, Dawid } 5706617338dSEd Tanous 5711e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Host state: " << hostState; 572c5b2abe0SLewanczyk, Dawid // Verify Host State 5731e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5741abe55efSEd Tanous { 57555c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 5766617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 5771abe55efSEd Tanous } 5781e1e598dSJonathan Doman else if (hostState == 5790fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5808c888608SGunnar Mills { 5818c888608SGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 5828c888608SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Quiesced"; 5838c888608SGunnar Mills } 5841e1e598dSJonathan Doman else if (hostState == 5850fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 58683935af9SAndrew Geissler { 58783935af9SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 58883935af9SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "InTest"; 58983935af9SAndrew Geissler } 5900fda0f12SGeorge Liu else if ( 5911e1e598dSJonathan Doman hostState == 5920fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5931a2a1437SAndrew Geissler { 5941a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOn"; 59515c27bf8SNoah Brewer aResp->res.jsonValue["Status"]["State"] = "Starting"; 5961a2a1437SAndrew Geissler } 597002d39b4SEd Tanous else if (hostState == 5980fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5991a2a1437SAndrew Geissler { 6001a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOff"; 6011a2a1437SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Disabled"; 6021a2a1437SAndrew Geissler } 6031abe55efSEd Tanous else 6041abe55efSEd Tanous { 60555c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 6066617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 607c5b2abe0SLewanczyk, Dawid } 6081e1e598dSJonathan Doman }); 609c5b2abe0SLewanczyk, Dawid } 610c5b2abe0SLewanczyk, Dawid 611c5b2abe0SLewanczyk, Dawid /** 612786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 613491d8ee7SSantosh Puranik * 614491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 615491d8ee7SSantosh Puranik * 616491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 617491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 618491d8ee7SSantosh Puranik */ 61923a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 620491d8ee7SSantosh Puranik { 621491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 622491d8ee7SSantosh Puranik { 623491d8ee7SSantosh Puranik return "None"; 624491d8ee7SSantosh Puranik } 6253174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 626491d8ee7SSantosh Puranik { 627491d8ee7SSantosh Puranik return "Hdd"; 628491d8ee7SSantosh Puranik } 6293174e4dfSEd Tanous if (dbusSource == 630a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 631491d8ee7SSantosh Puranik { 632491d8ee7SSantosh Puranik return "Cd"; 633491d8ee7SSantosh Puranik } 6343174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 635491d8ee7SSantosh Puranik { 636491d8ee7SSantosh Puranik return "Pxe"; 637491d8ee7SSantosh Puranik } 6383174e4dfSEd Tanous if (dbusSource == 639944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6409f16b2c1SJennifer Lee { 6419f16b2c1SJennifer Lee return "Usb"; 6429f16b2c1SJennifer Lee } 643491d8ee7SSantosh Puranik return ""; 644491d8ee7SSantosh Puranik } 645491d8ee7SSantosh Puranik 646491d8ee7SSantosh Puranik /** 647cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 648cd9a4666SKonstantin Aladyshev * 649cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 650cd9a4666SKonstantin Aladyshev * 651cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 652cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 653cd9a4666SKonstantin Aladyshev */ 654cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 655cd9a4666SKonstantin Aladyshev { 656cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 657cd9a4666SKonstantin Aladyshev { 658cd9a4666SKonstantin Aladyshev return "Legacy"; 659cd9a4666SKonstantin Aladyshev } 660cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 661cd9a4666SKonstantin Aladyshev { 662cd9a4666SKonstantin Aladyshev return "UEFI"; 663cd9a4666SKonstantin Aladyshev } 664cd9a4666SKonstantin Aladyshev return ""; 665cd9a4666SKonstantin Aladyshev } 666cd9a4666SKonstantin Aladyshev 667cd9a4666SKonstantin Aladyshev /** 668786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 669491d8ee7SSantosh Puranik * 670491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 671491d8ee7SSantosh Puranik * 672491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 673491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 674491d8ee7SSantosh Puranik */ 67523a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 676491d8ee7SSantosh Puranik { 677491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 678491d8ee7SSantosh Puranik { 679491d8ee7SSantosh Puranik return "None"; 680491d8ee7SSantosh Puranik } 6813174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 682491d8ee7SSantosh Puranik { 683491d8ee7SSantosh Puranik return "Diags"; 684491d8ee7SSantosh Puranik } 6853174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 686491d8ee7SSantosh Puranik { 687491d8ee7SSantosh Puranik return "BiosSetup"; 688491d8ee7SSantosh Puranik } 689491d8ee7SSantosh Puranik return ""; 690491d8ee7SSantosh Puranik } 691491d8ee7SSantosh Puranik 692491d8ee7SSantosh Puranik /** 693e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 694e43914b3SAndrew Geissler * 695e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 696e43914b3SAndrew Geissler * 697e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 698e43914b3SAndrew Geissler * translation cannot be done, returns "None". 699e43914b3SAndrew Geissler */ 700e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 701e43914b3SAndrew Geissler { 702e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 703e43914b3SAndrew Geissler // enum 704e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 705e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 706e43914b3SAndrew Geissler "ProgressStages.Unspecified") 707e43914b3SAndrew Geissler { 708e43914b3SAndrew Geissler rfBpLastState = "None"; 709e43914b3SAndrew Geissler } 710e43914b3SAndrew Geissler else if (dbusBootProgress == 711e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 712e43914b3SAndrew Geissler "PrimaryProcInit") 713e43914b3SAndrew Geissler { 714e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 715e43914b3SAndrew Geissler } 716e43914b3SAndrew Geissler else if (dbusBootProgress == 717e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 718e43914b3SAndrew Geissler "BusInit") 719e43914b3SAndrew Geissler { 720e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 721e43914b3SAndrew Geissler } 722e43914b3SAndrew Geissler else if (dbusBootProgress == 723e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 724e43914b3SAndrew Geissler "MemoryInit") 725e43914b3SAndrew Geissler { 726e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 727e43914b3SAndrew Geissler } 728e43914b3SAndrew Geissler else if (dbusBootProgress == 729e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 730e43914b3SAndrew Geissler "SecondaryProcInit") 731e43914b3SAndrew Geissler { 732e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 733e43914b3SAndrew Geissler } 734e43914b3SAndrew Geissler else if (dbusBootProgress == 735e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 736e43914b3SAndrew Geissler "PCIInit") 737e43914b3SAndrew Geissler { 738e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 739e43914b3SAndrew Geissler } 740e43914b3SAndrew Geissler else if (dbusBootProgress == 741e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 742e43914b3SAndrew Geissler "SystemSetup") 743e43914b3SAndrew Geissler { 744e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 745e43914b3SAndrew Geissler } 746e43914b3SAndrew Geissler else if (dbusBootProgress == 747e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 748e43914b3SAndrew Geissler "SystemInitComplete") 749e43914b3SAndrew Geissler { 750e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 751e43914b3SAndrew Geissler } 752e43914b3SAndrew Geissler else if (dbusBootProgress == 753e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 754e43914b3SAndrew Geissler "OSStart") 755e43914b3SAndrew Geissler { 756e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 757e43914b3SAndrew Geissler } 758e43914b3SAndrew Geissler else if (dbusBootProgress == 759e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 760e43914b3SAndrew Geissler "OSRunning") 761e43914b3SAndrew Geissler { 762e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 763e43914b3SAndrew Geissler } 764e43914b3SAndrew Geissler else 765e43914b3SAndrew Geissler { 766e43914b3SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 767e43914b3SAndrew Geissler << dbusBootProgress; 768e43914b3SAndrew Geissler // Just return the default 769e43914b3SAndrew Geissler } 770e43914b3SAndrew Geissler return rfBpLastState; 771e43914b3SAndrew Geissler } 772e43914b3SAndrew Geissler 773e43914b3SAndrew Geissler /** 774786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 775491d8ee7SSantosh Puranik * 776491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 777944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 778944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 779491d8ee7SSantosh Puranik * 780944ffaf9SJohnathan Mantey * @return Integer error code. 781491d8ee7SSantosh Puranik */ 7828d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 783944ffaf9SJohnathan Mantey const std::string& rfSource, 784944ffaf9SJohnathan Mantey std::string& bootSource, std::string& bootMode) 785491d8ee7SSantosh Puranik { 786c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 787c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 788944ffaf9SJohnathan Mantey 789491d8ee7SSantosh Puranik if (rfSource == "None") 790491d8ee7SSantosh Puranik { 791944ffaf9SJohnathan Mantey return 0; 792491d8ee7SSantosh Puranik } 7933174e4dfSEd Tanous if (rfSource == "Pxe") 794491d8ee7SSantosh Puranik { 795944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 796944ffaf9SJohnathan Mantey } 797944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 798944ffaf9SJohnathan Mantey { 799944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 800944ffaf9SJohnathan Mantey } 801944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 802944ffaf9SJohnathan Mantey { 803944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 804944ffaf9SJohnathan Mantey } 805944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 806944ffaf9SJohnathan Mantey { 807944ffaf9SJohnathan Mantey bootSource = 808944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 809944ffaf9SJohnathan Mantey } 810944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 811944ffaf9SJohnathan Mantey { 812944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 813491d8ee7SSantosh Puranik } 8149f16b2c1SJennifer Lee else if (rfSource == "Usb") 8159f16b2c1SJennifer Lee { 816944ffaf9SJohnathan Mantey bootSource = 817944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8189f16b2c1SJennifer Lee } 819491d8ee7SSantosh Puranik else 820491d8ee7SSantosh Puranik { 8210fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 8220fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideTarget: " 823944ffaf9SJohnathan Mantey << bootSource; 824944ffaf9SJohnathan Mantey messages::propertyValueNotInList(aResp->res, rfSource, 825944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 826944ffaf9SJohnathan Mantey return -1; 827491d8ee7SSantosh Puranik } 828944ffaf9SJohnathan Mantey return 0; 829491d8ee7SSantosh Puranik } 8301981771bSAli Ahmed 831978b8803SAndrew Geissler /** 832978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 833978b8803SAndrew Geissler * 834978b8803SAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 835978b8803SAndrew Geissler * 836978b8803SAndrew Geissler * @return None. 837978b8803SAndrew Geissler */ 8388d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 839978b8803SAndrew Geissler { 8401e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8411e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8421e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8431e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 844978b8803SAndrew Geissler [aResp](const boost::system::error_code ec, 8451e1e598dSJonathan Doman const std::string& bootProgressStr) { 846978b8803SAndrew Geissler if (ec) 847978b8803SAndrew Geissler { 848978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 849978b8803SAndrew Geissler // not found 850978b8803SAndrew Geissler return; 851978b8803SAndrew Geissler } 852978b8803SAndrew Geissler 8531e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr; 854978b8803SAndrew Geissler 855e43914b3SAndrew Geissler aResp->res.jsonValue["BootProgress"]["LastState"] = 856e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8571e1e598dSJonathan Doman }); 858978b8803SAndrew Geissler } 859491d8ee7SSantosh Puranik 860491d8ee7SSantosh Puranik /** 861b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 862b6d5d45cSHieu Huynh * 863b6d5d45cSHieu Huynh * @param[in] aResp Shared pointer for generating response message. 864b6d5d45cSHieu Huynh * 865b6d5d45cSHieu Huynh * @return None. 866b6d5d45cSHieu Huynh */ 867b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 868b6d5d45cSHieu Huynh const std::shared_ptr<bmcweb::AsyncResp>& aResp) 869b6d5d45cSHieu Huynh { 870b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 871b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 872b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 873b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 874b6d5d45cSHieu Huynh [aResp](const boost::system::error_code ec, 875b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 876b6d5d45cSHieu Huynh if (ec) 877b6d5d45cSHieu Huynh { 878b6d5d45cSHieu Huynh BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 879b6d5d45cSHieu Huynh return; 880b6d5d45cSHieu Huynh } 881b6d5d45cSHieu Huynh 882b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 883b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 884b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 885b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 886b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 887b6d5d45cSHieu Huynh 888b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 889b6d5d45cSHieu Huynh aResp->res.jsonValue["BootProgress"]["LastStateTime"] = 890b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 891b6d5d45cSHieu Huynh }); 892b6d5d45cSHieu Huynh } 893b6d5d45cSHieu Huynh 894b6d5d45cSHieu Huynh /** 895c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 896cd9a4666SKonstantin Aladyshev * 897cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 898cd9a4666SKonstantin Aladyshev * 899cd9a4666SKonstantin Aladyshev * @return None. 900cd9a4666SKonstantin Aladyshev */ 901cd9a4666SKonstantin Aladyshev 902c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 903cd9a4666SKonstantin Aladyshev { 9041e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9051e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9061e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9071e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 908cd9a4666SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 9091e1e598dSJonathan Doman const std::string& bootType) { 910cd9a4666SKonstantin Aladyshev if (ec) 911cd9a4666SKonstantin Aladyshev { 912cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 913cd9a4666SKonstantin Aladyshev return; 914cd9a4666SKonstantin Aladyshev } 915cd9a4666SKonstantin Aladyshev 9161e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot type: " << bootType; 917cd9a4666SKonstantin Aladyshev 918002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 919002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 920613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 921cd9a4666SKonstantin Aladyshev 9221e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 923cd9a4666SKonstantin Aladyshev if (rfType.empty()) 924cd9a4666SKonstantin Aladyshev { 925cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 926cd9a4666SKonstantin Aladyshev return; 927cd9a4666SKonstantin Aladyshev } 928cd9a4666SKonstantin Aladyshev 929cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9301e1e598dSJonathan Doman }); 931cd9a4666SKonstantin Aladyshev } 932cd9a4666SKonstantin Aladyshev 933cd9a4666SKonstantin Aladyshev /** 934c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 935491d8ee7SSantosh Puranik * 936491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 937491d8ee7SSantosh Puranik * 938491d8ee7SSantosh Puranik * @return None. 939491d8ee7SSantosh Puranik */ 940c21865c4SKonstantin Aladyshev 941c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 942491d8ee7SSantosh Puranik { 9431e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9441e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9451e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9461e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 947c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 9481e1e598dSJonathan Doman const std::string& bootModeStr) { 949491d8ee7SSantosh Puranik if (ec) 950491d8ee7SSantosh Puranik { 951491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 952491d8ee7SSantosh Puranik messages::internalError(aResp->res); 953491d8ee7SSantosh Puranik return; 954491d8ee7SSantosh Puranik } 955491d8ee7SSantosh Puranik 9561e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 957491d8ee7SSantosh Puranik 9580fda0f12SGeorge Liu aResp->res 9590fda0f12SGeorge Liu .jsonValue["Boot"] 960002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 961002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 962491d8ee7SSantosh Puranik 9631e1e598dSJonathan Doman if (bootModeStr != 964491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 965491d8ee7SSantosh Puranik { 9661e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 967491d8ee7SSantosh Puranik if (!rfMode.empty()) 968491d8ee7SSantosh Puranik { 969491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 970491d8ee7SSantosh Puranik rfMode; 971491d8ee7SSantosh Puranik } 972491d8ee7SSantosh Puranik } 9731e1e598dSJonathan Doman }); 974491d8ee7SSantosh Puranik } 975491d8ee7SSantosh Puranik 976491d8ee7SSantosh Puranik /** 977c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 978491d8ee7SSantosh Puranik * 979491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 980491d8ee7SSantosh Puranik * 981491d8ee7SSantosh Puranik * @return None. 982491d8ee7SSantosh Puranik */ 983c21865c4SKonstantin Aladyshev 984c21865c4SKonstantin Aladyshev inline void 985c21865c4SKonstantin Aladyshev getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 986491d8ee7SSantosh Puranik { 9871e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9881e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9891e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9901e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 991c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 9921e1e598dSJonathan Doman const std::string& bootSourceStr) { 993491d8ee7SSantosh Puranik if (ec) 994491d8ee7SSantosh Puranik { 995491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 9965ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 9975ef735c8SNan Zhou { 9985ef735c8SNan Zhou return; 9995ef735c8SNan Zhou } 1000491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1001491d8ee7SSantosh Puranik return; 1002491d8ee7SSantosh Puranik } 1003491d8ee7SSantosh Puranik 10041e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr; 1005491d8ee7SSantosh Puranik 10061e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1007491d8ee7SSantosh Puranik if (!rfSource.empty()) 1008491d8ee7SSantosh Puranik { 1009002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource; 1010491d8ee7SSantosh Puranik } 1011cd9a4666SKonstantin Aladyshev 1012cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1013cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1014c21865c4SKonstantin Aladyshev getBootOverrideMode(aResp); 10151e1e598dSJonathan Doman }); 1016491d8ee7SSantosh Puranik } 1017491d8ee7SSantosh Puranik 1018491d8ee7SSantosh Puranik /** 1019c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1020c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1021c21865c4SKonstantin Aladyshev * state 1022491d8ee7SSantosh Puranik * 1023491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1024491d8ee7SSantosh Puranik * 1025491d8ee7SSantosh Puranik * @return None. 1026491d8ee7SSantosh Puranik */ 1027491d8ee7SSantosh Puranik 1028c21865c4SKonstantin Aladyshev inline void 1029c21865c4SKonstantin Aladyshev processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1030c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1031c21865c4SKonstantin Aladyshev { 1032c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1033c21865c4SKonstantin Aladyshev { 1034c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; 1035c21865c4SKonstantin Aladyshev return; 1036c21865c4SKonstantin Aladyshev } 1037c21865c4SKonstantin Aladyshev 1038c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1039c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10401e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10411e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10421e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10431e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 10441e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, bool oneTimeSetting) { 1045491d8ee7SSantosh Puranik if (ec) 1046491d8ee7SSantosh Puranik { 1047491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1048c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1049491d8ee7SSantosh Puranik return; 1050491d8ee7SSantosh Puranik } 1051491d8ee7SSantosh Puranik 1052c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1053c21865c4SKonstantin Aladyshev { 1054002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once"; 1055c21865c4SKonstantin Aladyshev } 1056c21865c4SKonstantin Aladyshev else 1057c21865c4SKonstantin Aladyshev { 1058c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1059c21865c4SKonstantin Aladyshev "Continuous"; 1060c21865c4SKonstantin Aladyshev } 10611e1e598dSJonathan Doman }); 1062491d8ee7SSantosh Puranik } 1063491d8ee7SSantosh Puranik 1064491d8ee7SSantosh Puranik /** 1065c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1066c21865c4SKonstantin Aladyshev * 1067c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1068c21865c4SKonstantin Aladyshev * 1069c21865c4SKonstantin Aladyshev * @return None. 1070c21865c4SKonstantin Aladyshev */ 1071c21865c4SKonstantin Aladyshev 1072c21865c4SKonstantin Aladyshev inline void 1073c21865c4SKonstantin Aladyshev getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1074c21865c4SKonstantin Aladyshev { 10751e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10761e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10771e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10781e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1079c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 10801e1e598dSJonathan Doman const bool bootOverrideEnable) { 1081c21865c4SKonstantin Aladyshev if (ec) 1082c21865c4SKonstantin Aladyshev { 1083c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 10845ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10855ef735c8SNan Zhou { 10865ef735c8SNan Zhou return; 10875ef735c8SNan Zhou } 1088c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1089c21865c4SKonstantin Aladyshev return; 1090c21865c4SKonstantin Aladyshev } 1091c21865c4SKonstantin Aladyshev 10921e1e598dSJonathan Doman processBootOverrideEnable(aResp, bootOverrideEnable); 10931e1e598dSJonathan Doman }); 1094c21865c4SKonstantin Aladyshev } 1095c21865c4SKonstantin Aladyshev 1096c21865c4SKonstantin Aladyshev /** 1097c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1098c21865c4SKonstantin Aladyshev * 1099c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1100c21865c4SKonstantin Aladyshev * 1101c21865c4SKonstantin Aladyshev * @return None. 1102c21865c4SKonstantin Aladyshev */ 1103c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1104c21865c4SKonstantin Aladyshev { 1105c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1106c21865c4SKonstantin Aladyshev 1107c21865c4SKonstantin Aladyshev getBootOverrideSource(aResp); 1108c21865c4SKonstantin Aladyshev getBootOverrideType(aResp); 1109c21865c4SKonstantin Aladyshev getBootOverrideEnable(aResp); 1110c21865c4SKonstantin Aladyshev } 1111c21865c4SKonstantin Aladyshev 1112c21865c4SKonstantin Aladyshev /** 1113c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1114c0557e1aSGunnar Mills * 1115c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1116c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1117c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1118c0557e1aSGunnar Mills * last power operation time. 1119c0557e1aSGunnar Mills * 1120c0557e1aSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 1121c0557e1aSGunnar Mills * 1122c0557e1aSGunnar Mills * @return None. 1123c0557e1aSGunnar Mills */ 11248d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1125c0557e1aSGunnar Mills { 1126c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1127c0557e1aSGunnar Mills 11281e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11291e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11301e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11311e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 11321e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, uint64_t lastResetTime) { 1133c0557e1aSGunnar Mills if (ec) 1134c0557e1aSGunnar Mills { 1135c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1136c0557e1aSGunnar Mills return; 1137c0557e1aSGunnar Mills } 1138c0557e1aSGunnar Mills 1139c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1140c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11411e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1142c0557e1aSGunnar Mills 1143c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1144c0557e1aSGunnar Mills aResp->res.jsonValue["LastResetTime"] = 11452b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11461e1e598dSJonathan Doman }); 1147c0557e1aSGunnar Mills } 1148c0557e1aSGunnar Mills 1149c0557e1aSGunnar Mills /** 11506bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 11516bd5a8d2SGunnar Mills * 11526bd5a8d2SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 11536bd5a8d2SGunnar Mills * 11546bd5a8d2SGunnar Mills * @return None. 11556bd5a8d2SGunnar Mills */ 11568d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 11576bd5a8d2SGunnar Mills { 11586bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 11596bd5a8d2SGunnar Mills 11601e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11611e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11621e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 11631e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 11641e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, bool autoRebootEnabled) { 11656bd5a8d2SGunnar Mills if (ec) 11666bd5a8d2SGunnar Mills { 11676bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 11686bd5a8d2SGunnar Mills return; 11696bd5a8d2SGunnar Mills } 11706bd5a8d2SGunnar Mills 11711e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled; 1172e05aec50SEd Tanous if (autoRebootEnabled) 11736bd5a8d2SGunnar Mills { 11746bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 11756bd5a8d2SGunnar Mills "RetryAttempts"; 11766bd5a8d2SGunnar Mills // If AutomaticRetry (AutoReboot) is enabled see how many 11776bd5a8d2SGunnar Mills // attempts are left 11781e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint32_t>( 1179002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 11801e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 11811e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootAttempts", 11821e1e598dSJonathan Doman "AttemptsLeft", 1183cb13a392SEd Tanous [aResp](const boost::system::error_code ec2, 1184914e2d5dSEd Tanous const uint32_t autoRebootAttemptsLeft) { 1185cb13a392SEd Tanous if (ec2) 11866bd5a8d2SGunnar Mills { 1187cb13a392SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2; 11886bd5a8d2SGunnar Mills return; 11896bd5a8d2SGunnar Mills } 11906bd5a8d2SGunnar Mills 11916bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: " 11921e1e598dSJonathan Doman << autoRebootAttemptsLeft; 11936bd5a8d2SGunnar Mills 11946bd5a8d2SGunnar Mills aResp->res 1195002d39b4SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 11961e1e598dSJonathan Doman autoRebootAttemptsLeft; 11971e1e598dSJonathan Doman }); 11986bd5a8d2SGunnar Mills } 11996bd5a8d2SGunnar Mills else 12006bd5a8d2SGunnar Mills { 1201002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled"; 12026bd5a8d2SGunnar Mills } 12036bd5a8d2SGunnar Mills 12046bd5a8d2SGunnar Mills // Not on D-Bus. Hardcoded here: 12056bd5a8d2SGunnar Mills // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71 12066bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3; 120769f35306SGunnar Mills 120869f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 120969f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 121069f35306SGunnar Mills // RetryAttempts. 1211002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 12120fda0f12SGeorge Liu ["AutomaticRetryConfig@Redfish.AllowableValues"] = { 12130fda0f12SGeorge Liu "Disabled", "RetryAttempts"}; 12141e1e598dSJonathan Doman }); 12156bd5a8d2SGunnar Mills } 12166bd5a8d2SGunnar Mills 12176bd5a8d2SGunnar Mills /** 1218c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1219c6a620f2SGeorge Liu * 1220c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1221c6a620f2SGeorge Liu * 1222c6a620f2SGeorge Liu * @return None. 1223c6a620f2SGeorge Liu */ 12248d1b46d7Szhanghch05 inline void 12258d1b46d7Szhanghch05 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1226c6a620f2SGeorge Liu { 1227c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1228c6a620f2SGeorge Liu 12291e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 12301e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12311e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 12321e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 12331e1e598dSJonathan Doman [aResp](const boost::system::error_code ec, const std::string& policy) { 1234c6a620f2SGeorge Liu if (ec) 1235c6a620f2SGeorge Liu { 1236c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1237c6a620f2SGeorge Liu return; 1238c6a620f2SGeorge Liu } 1239c6a620f2SGeorge Liu 12400fda0f12SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 12410fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn", 1242c6a620f2SGeorge Liu "AlwaysOn"}, 12430fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff", 1244c6a620f2SGeorge Liu "AlwaysOff"}, 12450fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore", 12464ed47cb8SMatthew Barth "LastState"}, 12474ed47cb8SMatthew Barth // Return `AlwaysOff` when power restore policy set to "None" 12484ed47cb8SMatthew Barth {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None", 12494ed47cb8SMatthew Barth "AlwaysOff"}}; 1250c6a620f2SGeorge Liu 12511e1e598dSJonathan Doman auto policyMapsIt = policyMaps.find(policy); 1252c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1253c6a620f2SGeorge Liu { 1254c6a620f2SGeorge Liu messages::internalError(aResp->res); 1255c6a620f2SGeorge Liu return; 1256c6a620f2SGeorge Liu } 1257c6a620f2SGeorge Liu 1258c6a620f2SGeorge Liu aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second; 12591e1e598dSJonathan Doman }); 1260c6a620f2SGeorge Liu } 1261c6a620f2SGeorge Liu 1262c6a620f2SGeorge Liu /** 12631981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 12641981771bSAli Ahmed * TPM is required for booting the host. 12651981771bSAli Ahmed * 12661981771bSAli Ahmed * @param[in] aResp Shared pointer for generating response message. 12671981771bSAli Ahmed * 12681981771bSAli Ahmed * @return None. 12691981771bSAli Ahmed */ 12701981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 12711981771bSAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp) 12721981771bSAli Ahmed { 12731981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 12741981771bSAli Ahmed 12751981771bSAli Ahmed crow::connections::systemBus->async_method_call( 1276b9d36b47SEd Tanous [aResp](const boost::system::error_code ec, 1277b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 12781981771bSAli Ahmed if (ec) 12791981771bSAli Ahmed { 1280002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1281002d39b4SEd Tanous << ec; 12821981771bSAli Ahmed // This is an optional D-Bus object so just return if 12831981771bSAli Ahmed // error occurs 12841981771bSAli Ahmed return; 12851981771bSAli Ahmed } 128626f6976fSEd Tanous if (subtree.empty()) 12871981771bSAli Ahmed { 12881981771bSAli Ahmed // As noted above, this is an optional interface so just return 12891981771bSAli Ahmed // if there is no instance found 12901981771bSAli Ahmed return; 12911981771bSAli Ahmed } 12921981771bSAli Ahmed 12931981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 12941981771bSAli Ahmed if (subtree.size() > 1) 12951981771bSAli Ahmed { 12961981771bSAli Ahmed BMCWEB_LOG_DEBUG 12971981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 12981981771bSAli Ahmed << subtree.size(); 12991981771bSAli Ahmed // Throw an internal Error and return 13001981771bSAli Ahmed messages::internalError(aResp->res); 13011981771bSAli Ahmed return; 13021981771bSAli Ahmed } 13031981771bSAli Ahmed 13041981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 13051981771bSAli Ahmed // field 13061981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 13071981771bSAli Ahmed { 13081981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 13091981771bSAli Ahmed messages::internalError(aResp->res); 13101981771bSAli Ahmed return; 13111981771bSAli Ahmed } 13121981771bSAli Ahmed 13131981771bSAli Ahmed const std::string& path = subtree[0].first; 13141981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 13151981771bSAli Ahmed 13161981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 13171e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 13181e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 13191e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 13208a592810SEd Tanous [aResp](const boost::system::error_code ec2, bool tpmRequired) { 13218a592810SEd Tanous if (ec2) 13221981771bSAli Ahmed { 1323002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get" 13248a592810SEd Tanous << ec2; 13251981771bSAli Ahmed messages::internalError(aResp->res); 13261981771bSAli Ahmed return; 13271981771bSAli Ahmed } 13281981771bSAli Ahmed 13291e1e598dSJonathan Doman if (tpmRequired) 13301981771bSAli Ahmed { 1331002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 13321981771bSAli Ahmed "Required"; 13331981771bSAli Ahmed } 13341981771bSAli Ahmed else 13351981771bSAli Ahmed { 1336002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 13371981771bSAli Ahmed "Disabled"; 13381981771bSAli Ahmed } 13391e1e598dSJonathan Doman }); 13401981771bSAli Ahmed }, 13411981771bSAli Ahmed "xyz.openbmc_project.ObjectMapper", 13421981771bSAli Ahmed "/xyz/openbmc_project/object_mapper", 13431981771bSAli Ahmed "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 13441981771bSAli Ahmed std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"}); 13451981771bSAli Ahmed } 13461981771bSAli Ahmed 13471981771bSAli Ahmed /** 13481c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 13491c05dae3SAli Ahmed * TPM is required for booting the host. 13501c05dae3SAli Ahmed * 13511c05dae3SAli Ahmed * @param[in] aResp Shared pointer for generating response message. 13521c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 13531c05dae3SAli Ahmed * 13541c05dae3SAli Ahmed * @return None. 13551c05dae3SAli Ahmed */ 13561c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 13571c05dae3SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired) 13581c05dae3SAli Ahmed { 13591c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 13601c05dae3SAli Ahmed 13611c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 1362b9d36b47SEd Tanous [aResp, tpmRequired](const boost::system::error_code ec, 1363b9d36b47SEd Tanous dbus::utility::MapperGetSubTreeResponse& subtree) { 13641c05dae3SAli Ahmed if (ec) 13651c05dae3SAli Ahmed { 1366002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1367002d39b4SEd Tanous << ec; 13681c05dae3SAli Ahmed messages::internalError(aResp->res); 13691c05dae3SAli Ahmed return; 13701c05dae3SAli Ahmed } 137126f6976fSEd Tanous if (subtree.empty()) 13721c05dae3SAli Ahmed { 13731c05dae3SAli Ahmed messages::propertyValueNotInList(aResp->res, "ComputerSystem", 13741c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 13751c05dae3SAli Ahmed return; 13761c05dae3SAli Ahmed } 13771c05dae3SAli Ahmed 13781c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 13791c05dae3SAli Ahmed if (subtree.size() > 1) 13801c05dae3SAli Ahmed { 13811c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 13821c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 13831c05dae3SAli Ahmed << subtree.size(); 13841c05dae3SAli Ahmed // Throw an internal Error and return 13851c05dae3SAli Ahmed messages::internalError(aResp->res); 13861c05dae3SAli Ahmed return; 13871c05dae3SAli Ahmed } 13881c05dae3SAli Ahmed 13891c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 13901c05dae3SAli Ahmed // field 13911c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 13921c05dae3SAli Ahmed { 13931c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 13941c05dae3SAli Ahmed messages::internalError(aResp->res); 13951c05dae3SAli Ahmed return; 13961c05dae3SAli Ahmed } 13971c05dae3SAli Ahmed 13981c05dae3SAli Ahmed const std::string& path = subtree[0].first; 13991c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14001c05dae3SAli Ahmed 14011c05dae3SAli Ahmed if (serv.empty()) 14021c05dae3SAli Ahmed { 14031c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 14041c05dae3SAli Ahmed messages::internalError(aResp->res); 14051c05dae3SAli Ahmed return; 14061c05dae3SAli Ahmed } 14071c05dae3SAli Ahmed 14081c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 14091c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 14108a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 14118a592810SEd Tanous if (ec2) 14121c05dae3SAli Ahmed { 14130fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 14140fda0f12SGeorge Liu << "DBUS response error: Set TrustedModuleRequiredToBoot" 14158a592810SEd Tanous << ec2; 14161c05dae3SAli Ahmed messages::internalError(aResp->res); 14171c05dae3SAli Ahmed return; 14181c05dae3SAli Ahmed } 14191c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 14201c05dae3SAli Ahmed }, 14211c05dae3SAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Set", 14221c05dae3SAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1423168e20c1SEd Tanous dbus::utility::DbusVariantType(tpmRequired)); 14241c05dae3SAli Ahmed }, 14251c05dae3SAli Ahmed "xyz.openbmc_project.ObjectMapper", 14261c05dae3SAli Ahmed "/xyz/openbmc_project/object_mapper", 14271c05dae3SAli Ahmed "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 14281c05dae3SAli Ahmed std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"}); 14291c05dae3SAli Ahmed } 14301c05dae3SAli Ahmed 14311c05dae3SAli Ahmed /** 1432491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1433491d8ee7SSantosh Puranik * 1434491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1435cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1436cd9a4666SKonstantin Aladyshev * @return Integer error code. 1437cd9a4666SKonstantin Aladyshev */ 1438cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1439cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1440cd9a4666SKonstantin Aladyshev { 1441c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1442cd9a4666SKonstantin Aladyshev 1443c21865c4SKonstantin Aladyshev if (!bootType) 1444cd9a4666SKonstantin Aladyshev { 1445c21865c4SKonstantin Aladyshev return; 1446c21865c4SKonstantin Aladyshev } 1447c21865c4SKonstantin Aladyshev 1448cd9a4666SKonstantin Aladyshev // Source target specified 1449cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1450cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1451cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1452cd9a4666SKonstantin Aladyshev { 1453cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1454cd9a4666SKonstantin Aladyshev } 1455cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1456cd9a4666SKonstantin Aladyshev { 1457cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1458cd9a4666SKonstantin Aladyshev } 1459cd9a4666SKonstantin Aladyshev else 1460cd9a4666SKonstantin Aladyshev { 1461cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1462cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1463cd9a4666SKonstantin Aladyshev << *bootType; 1464cd9a4666SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootType, 1465cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1466cd9a4666SKonstantin Aladyshev return; 1467cd9a4666SKonstantin Aladyshev } 1468cd9a4666SKonstantin Aladyshev 1469cd9a4666SKonstantin Aladyshev // Act on validated parameters 1470cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1471cd9a4666SKonstantin Aladyshev 1472cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1473c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1474cd9a4666SKonstantin Aladyshev if (ec) 1475cd9a4666SKonstantin Aladyshev { 1476cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1477cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1478cd9a4666SKonstantin Aladyshev { 1479cd9a4666SKonstantin Aladyshev messages::resourceNotFound(aResp->res, "Set", "BootType"); 1480cd9a4666SKonstantin Aladyshev return; 1481cd9a4666SKonstantin Aladyshev } 1482cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 1483cd9a4666SKonstantin Aladyshev return; 1484cd9a4666SKonstantin Aladyshev } 1485cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1486cd9a4666SKonstantin Aladyshev }, 1487c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1488c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1489cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1490cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1491168e20c1SEd Tanous dbus::utility::DbusVariantType(bootTypeStr)); 1492cd9a4666SKonstantin Aladyshev } 1493cd9a4666SKonstantin Aladyshev 1494cd9a4666SKonstantin Aladyshev /** 1495cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1496cd9a4666SKonstantin Aladyshev * 1497cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1498c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1499c21865c4SKonstantin Aladyshev * @return Integer error code. 1500c21865c4SKonstantin Aladyshev */ 1501c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1502c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1503c21865c4SKonstantin Aladyshev { 1504c21865c4SKonstantin Aladyshev if (!bootEnable) 1505c21865c4SKonstantin Aladyshev { 1506c21865c4SKonstantin Aladyshev return; 1507c21865c4SKonstantin Aladyshev } 1508c21865c4SKonstantin Aladyshev // Source target specified 1509c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1510c21865c4SKonstantin Aladyshev 1511c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1512c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1513c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1514c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1515c21865c4SKonstantin Aladyshev { 1516c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1517c21865c4SKonstantin Aladyshev } 1518c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1519c21865c4SKonstantin Aladyshev { 1520c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1521c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1522c21865c4SKonstantin Aladyshev } 1523c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1524c21865c4SKonstantin Aladyshev { 1525c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1526c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1527c21865c4SKonstantin Aladyshev } 1528c21865c4SKonstantin Aladyshev else 1529c21865c4SKonstantin Aladyshev { 15300fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 15310fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideEnabled: " 1532c21865c4SKonstantin Aladyshev << *bootEnable; 1533c21865c4SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootEnable, 1534c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1535c21865c4SKonstantin Aladyshev return; 1536c21865c4SKonstantin Aladyshev } 1537c21865c4SKonstantin Aladyshev 1538c21865c4SKonstantin Aladyshev // Act on validated parameters 1539c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1540c21865c4SKonstantin Aladyshev 1541c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 15428a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 15438a592810SEd Tanous if (ec2) 1544c21865c4SKonstantin Aladyshev { 15458a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1546c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1547c21865c4SKonstantin Aladyshev return; 1548c21865c4SKonstantin Aladyshev } 1549c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1550c21865c4SKonstantin Aladyshev }, 1551c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1552c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1553c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1554c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1555168e20c1SEd Tanous dbus::utility::DbusVariantType(bootOverrideEnable)); 1556c21865c4SKonstantin Aladyshev 1557c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1558c21865c4SKonstantin Aladyshev { 1559c21865c4SKonstantin Aladyshev return; 1560c21865c4SKonstantin Aladyshev } 1561c21865c4SKonstantin Aladyshev 1562c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1563c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1564c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1565c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1566c21865c4SKonstantin Aladyshev 1567c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1568c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1569c21865c4SKonstantin Aladyshev if (ec) 1570c21865c4SKonstantin Aladyshev { 1571c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1572c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1573c21865c4SKonstantin Aladyshev return; 1574c21865c4SKonstantin Aladyshev } 1575c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1576c21865c4SKonstantin Aladyshev }, 1577c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1578c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1579c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1580c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1581168e20c1SEd Tanous dbus::utility::DbusVariantType(!bootOverridePersistent)); 1582c21865c4SKonstantin Aladyshev } 1583c21865c4SKonstantin Aladyshev 1584c21865c4SKonstantin Aladyshev /** 1585c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1586c21865c4SKonstantin Aladyshev * 1587c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1588491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1589491d8ee7SSantosh Puranik * 1590265c1602SJohnathan Mantey * @return Integer error code. 1591491d8ee7SSantosh Puranik */ 1592cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1593cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1594491d8ee7SSantosh Puranik { 1595c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1596c21865c4SKonstantin Aladyshev std::string bootModeStr; 1597944ffaf9SJohnathan Mantey 1598c21865c4SKonstantin Aladyshev if (!bootSource) 1599491d8ee7SSantosh Puranik { 1600c21865c4SKonstantin Aladyshev return; 1601c21865c4SKonstantin Aladyshev } 1602c21865c4SKonstantin Aladyshev 1603491d8ee7SSantosh Puranik // Source target specified 1604491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1605491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1606e662eae8SEd Tanous if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) != 1607e662eae8SEd Tanous 0) 1608491d8ee7SSantosh Puranik { 1609944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1610944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1611491d8ee7SSantosh Puranik << *bootSource; 1612491d8ee7SSantosh Puranik messages::propertyValueNotInList(aResp->res, *bootSource, 1613491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1614491d8ee7SSantosh Puranik return; 1615491d8ee7SSantosh Puranik } 1616491d8ee7SSantosh Puranik 1617944ffaf9SJohnathan Mantey // Act on validated parameters 1618944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1619944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1620944ffaf9SJohnathan Mantey 1621491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1622491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1623491d8ee7SSantosh Puranik if (ec) 1624491d8ee7SSantosh Puranik { 1625491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1626491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1627491d8ee7SSantosh Puranik return; 1628491d8ee7SSantosh Puranik } 1629491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1630491d8ee7SSantosh Puranik }, 1631c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1632c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1633491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1634491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1635168e20c1SEd Tanous dbus::utility::DbusVariantType(bootSourceStr)); 1636944ffaf9SJohnathan Mantey 1637491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1638491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1639491d8ee7SSantosh Puranik if (ec) 1640491d8ee7SSantosh Puranik { 1641491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1642491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1643491d8ee7SSantosh Puranik return; 1644491d8ee7SSantosh Puranik } 1645491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1646491d8ee7SSantosh Puranik }, 1647c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1648c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1649491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1650491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1651168e20c1SEd Tanous dbus::utility::DbusVariantType(bootModeStr)); 1652cd9a4666SKonstantin Aladyshev } 1653944ffaf9SJohnathan Mantey 1654cd9a4666SKonstantin Aladyshev /** 1655c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1656491d8ee7SSantosh Puranik * 1657491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1658491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1659cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1660491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1661491d8ee7SSantosh Puranik * 1662265c1602SJohnathan Mantey * @return Integer error code. 1663491d8ee7SSantosh Puranik */ 1664c21865c4SKonstantin Aladyshev 1665c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1666c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1667c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1668c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1669491d8ee7SSantosh Puranik { 1670491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1671491d8ee7SSantosh Puranik 1672c21865c4SKonstantin Aladyshev setBootModeOrSource(aResp, bootSource); 1673c21865c4SKonstantin Aladyshev setBootType(aResp, bootType); 1674c21865c4SKonstantin Aladyshev setBootEnable(aResp, bootEnable); 1675491d8ee7SSantosh Puranik } 1676491d8ee7SSantosh Puranik 1677c6a620f2SGeorge Liu /** 167898e386ecSGunnar Mills * @brief Sets AssetTag 167998e386ecSGunnar Mills * 168098e386ecSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 168198e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 168298e386ecSGunnar Mills * 168398e386ecSGunnar Mills * @return None. 168498e386ecSGunnar Mills */ 16858d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 168698e386ecSGunnar Mills const std::string& assetTag) 168798e386ecSGunnar Mills { 168898e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 1689b9d36b47SEd Tanous [aResp, 1690b9d36b47SEd Tanous assetTag](const boost::system::error_code ec, 1691b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 169298e386ecSGunnar Mills if (ec) 169398e386ecSGunnar Mills { 169498e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 169598e386ecSGunnar Mills messages::internalError(aResp->res); 169698e386ecSGunnar Mills return; 169798e386ecSGunnar Mills } 169826f6976fSEd Tanous if (subtree.empty()) 169998e386ecSGunnar Mills { 170098e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 170198e386ecSGunnar Mills messages::internalError(aResp->res); 170298e386ecSGunnar Mills return; 170398e386ecSGunnar Mills } 170498e386ecSGunnar Mills // Assume only 1 system D-Bus object 170598e386ecSGunnar Mills // Throw an error if there is more than 1 170698e386ecSGunnar Mills if (subtree.size() > 1) 170798e386ecSGunnar Mills { 170898e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 170998e386ecSGunnar Mills messages::internalError(aResp->res); 171098e386ecSGunnar Mills return; 171198e386ecSGunnar Mills } 171298e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 171398e386ecSGunnar Mills { 171498e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 171598e386ecSGunnar Mills messages::internalError(aResp->res); 171698e386ecSGunnar Mills return; 171798e386ecSGunnar Mills } 171898e386ecSGunnar Mills 171998e386ecSGunnar Mills const std::string& path = subtree[0].first; 172098e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 172198e386ecSGunnar Mills 172298e386ecSGunnar Mills if (service.empty()) 172398e386ecSGunnar Mills { 172498e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 172598e386ecSGunnar Mills messages::internalError(aResp->res); 172698e386ecSGunnar Mills return; 172798e386ecSGunnar Mills } 172898e386ecSGunnar Mills 172998e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 173098e386ecSGunnar Mills [aResp](const boost::system::error_code ec2) { 173198e386ecSGunnar Mills if (ec2) 173298e386ecSGunnar Mills { 1733002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set " 1734002d39b4SEd Tanous << ec2; 173598e386ecSGunnar Mills messages::internalError(aResp->res); 173698e386ecSGunnar Mills return; 173798e386ecSGunnar Mills } 173898e386ecSGunnar Mills }, 173998e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 174098e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 1741168e20c1SEd Tanous dbus::utility::DbusVariantType(assetTag)); 174298e386ecSGunnar Mills }, 174398e386ecSGunnar Mills "xyz.openbmc_project.ObjectMapper", 174498e386ecSGunnar Mills "/xyz/openbmc_project/object_mapper", 174598e386ecSGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 174698e386ecSGunnar Mills "/xyz/openbmc_project/inventory", int32_t(0), 174798e386ecSGunnar Mills std::array<const char*, 1>{ 174898e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Item.System"}); 174998e386ecSGunnar Mills } 175098e386ecSGunnar Mills 175198e386ecSGunnar Mills /** 175269f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 175369f35306SGunnar Mills * 175469f35306SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 175569f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 175669f35306SGunnar Mills * 175769f35306SGunnar Mills * @return None. 175869f35306SGunnar Mills */ 17598d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1760f23b7296SEd Tanous const std::string& automaticRetryConfig) 176169f35306SGunnar Mills { 176269f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 176369f35306SGunnar Mills 176469f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1765543f4400SEd Tanous bool autoRebootEnabled = false; 176669f35306SGunnar Mills 176769f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 176869f35306SGunnar Mills { 176969f35306SGunnar Mills autoRebootEnabled = false; 177069f35306SGunnar Mills } 177169f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 177269f35306SGunnar Mills { 177369f35306SGunnar Mills autoRebootEnabled = true; 177469f35306SGunnar Mills } 177569f35306SGunnar Mills else 177669f35306SGunnar Mills { 17770fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: " 177869f35306SGunnar Mills << automaticRetryConfig; 177969f35306SGunnar Mills messages::propertyValueNotInList(aResp->res, automaticRetryConfig, 178069f35306SGunnar Mills "AutomaticRetryConfig"); 178169f35306SGunnar Mills return; 178269f35306SGunnar Mills } 178369f35306SGunnar Mills 178469f35306SGunnar Mills crow::connections::systemBus->async_method_call( 178569f35306SGunnar Mills [aResp](const boost::system::error_code ec) { 178669f35306SGunnar Mills if (ec) 178769f35306SGunnar Mills { 178869f35306SGunnar Mills messages::internalError(aResp->res); 178969f35306SGunnar Mills return; 179069f35306SGunnar Mills } 179169f35306SGunnar Mills }, 179269f35306SGunnar Mills "xyz.openbmc_project.Settings", 179369f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 179469f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 179569f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1796168e20c1SEd Tanous dbus::utility::DbusVariantType(autoRebootEnabled)); 179769f35306SGunnar Mills } 179869f35306SGunnar Mills 179969f35306SGunnar Mills /** 1800c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1801c6a620f2SGeorge Liu * 1802c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1803c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1804c6a620f2SGeorge Liu * 1805c6a620f2SGeorge Liu * @return None. 1806c6a620f2SGeorge Liu */ 18078d1b46d7Szhanghch05 inline void 18088d1b46d7Szhanghch05 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 18094e69c904SGunnar Mills const std::string& policy) 1810c6a620f2SGeorge Liu { 1811c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1812c6a620f2SGeorge Liu 1813c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 18140fda0f12SGeorge Liu {"AlwaysOn", 18150fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"}, 18160fda0f12SGeorge Liu {"AlwaysOff", 18170fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"}, 18180fda0f12SGeorge Liu {"LastState", 18190fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}}; 1820c6a620f2SGeorge Liu 1821c6a620f2SGeorge Liu std::string powerRestorPolicy; 1822c6a620f2SGeorge Liu 18234e69c904SGunnar Mills auto policyMapsIt = policyMaps.find(policy); 1824c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1825c6a620f2SGeorge Liu { 18264e69c904SGunnar Mills messages::propertyValueNotInList(aResp->res, policy, 18274e69c904SGunnar Mills "PowerRestorePolicy"); 1828c6a620f2SGeorge Liu return; 1829c6a620f2SGeorge Liu } 1830c6a620f2SGeorge Liu 1831c6a620f2SGeorge Liu powerRestorPolicy = policyMapsIt->second; 1832c6a620f2SGeorge Liu 1833c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1834c6a620f2SGeorge Liu [aResp](const boost::system::error_code ec) { 1835c6a620f2SGeorge Liu if (ec) 1836c6a620f2SGeorge Liu { 1837c6a620f2SGeorge Liu messages::internalError(aResp->res); 1838c6a620f2SGeorge Liu return; 1839c6a620f2SGeorge Liu } 1840c6a620f2SGeorge Liu }, 1841c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1842c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1843c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1844c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1845168e20c1SEd Tanous dbus::utility::DbusVariantType(powerRestorPolicy)); 1846c6a620f2SGeorge Liu } 1847c6a620f2SGeorge Liu 1848a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 1849a6349918SAppaRao Puli /** 1850a6349918SAppaRao Puli * @brief Retrieves provisioning status 1851a6349918SAppaRao Puli * 1852a6349918SAppaRao Puli * @param[in] aResp Shared pointer for completing asynchronous calls. 1853a6349918SAppaRao Puli * 1854a6349918SAppaRao Puli * @return None. 1855a6349918SAppaRao Puli */ 18568d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp) 1857a6349918SAppaRao Puli { 1858a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 1859bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1860bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1861bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 1862a6349918SAppaRao Puli [aResp](const boost::system::error_code ec, 1863b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1864b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1865b99fb1a9SAppaRao Puli aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 186650626f4fSJames Feist aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 186750626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 186850626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 186950626f4fSJames Feist 1870a6349918SAppaRao Puli if (ec) 1871a6349918SAppaRao Puli { 1872a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1873b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1874b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1875a6349918SAppaRao Puli return; 1876a6349918SAppaRao Puli } 1877a6349918SAppaRao Puli 1878a6349918SAppaRao Puli const bool* provState = nullptr; 1879a6349918SAppaRao Puli const bool* lockState = nullptr; 1880bc1d29deSKrzysztof Grobelny 1881bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 18820d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 18830d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 1884bc1d29deSKrzysztof Grobelny 1885bc1d29deSKrzysztof Grobelny if (!success) 1886a6349918SAppaRao Puli { 1887bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 1888bc1d29deSKrzysztof Grobelny return; 1889a6349918SAppaRao Puli } 1890a6349918SAppaRao Puli 1891a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 1892a6349918SAppaRao Puli { 1893a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 1894a6349918SAppaRao Puli messages::internalError(aResp->res); 1895a6349918SAppaRao Puli return; 1896a6349918SAppaRao Puli } 1897a6349918SAppaRao Puli 1898a6349918SAppaRao Puli if (*provState == true) 1899a6349918SAppaRao Puli { 1900a6349918SAppaRao Puli if (*lockState == true) 1901a6349918SAppaRao Puli { 1902a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 1903a6349918SAppaRao Puli } 1904a6349918SAppaRao Puli else 1905a6349918SAppaRao Puli { 1906a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 1907a6349918SAppaRao Puli } 1908a6349918SAppaRao Puli } 1909a6349918SAppaRao Puli else 1910a6349918SAppaRao Puli { 1911a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1912a6349918SAppaRao Puli } 1913bc1d29deSKrzysztof Grobelny }); 1914a6349918SAppaRao Puli } 1915a6349918SAppaRao Puli #endif 1916a6349918SAppaRao Puli 1917491d8ee7SSantosh Puranik /** 19183a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 19193a2d0424SChris Cain * 19203a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 19213a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 19223a2d0424SChris Cain * 19233a2d0424SChris Cain * @return None. 19243a2d0424SChris Cain */ 19253a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 19263a2d0424SChris Cain const std::string& modeValue) 19273a2d0424SChris Cain { 19280fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 19293a2d0424SChris Cain { 19303a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "Static"; 19313a2d0424SChris Cain } 19320fda0f12SGeorge Liu else if ( 19330fda0f12SGeorge Liu modeValue == 19340fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 19353a2d0424SChris Cain { 19363a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 19373a2d0424SChris Cain } 19380fda0f12SGeorge Liu else if (modeValue == 19390fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 19403a2d0424SChris Cain { 19413a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "PowerSaving"; 19423a2d0424SChris Cain } 19430fda0f12SGeorge Liu else if (modeValue == 19440fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 19453a2d0424SChris Cain { 19463a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "OEM"; 19473a2d0424SChris Cain } 19483a2d0424SChris Cain else 19493a2d0424SChris Cain { 19503a2d0424SChris Cain // Any other values would be invalid 19513a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 19523a2d0424SChris Cain messages::internalError(aResp->res); 19533a2d0424SChris Cain } 19543a2d0424SChris Cain } 19553a2d0424SChris Cain 19563a2d0424SChris Cain /** 19573a2d0424SChris Cain * @brief Retrieves system power mode 19583a2d0424SChris Cain * 19593a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 19603a2d0424SChris Cain * 19613a2d0424SChris Cain * @return None. 19623a2d0424SChris Cain */ 19633a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 19643a2d0424SChris Cain { 19653a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 19663a2d0424SChris Cain 19673a2d0424SChris Cain // Get Power Mode object path: 19683a2d0424SChris Cain crow::connections::systemBus->async_method_call( 1969b9d36b47SEd Tanous [aResp](const boost::system::error_code ec, 1970b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 19713a2d0424SChris Cain if (ec) 19723a2d0424SChris Cain { 1973002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 1974002d39b4SEd Tanous << ec; 19753a2d0424SChris Cain // This is an optional D-Bus object so just return if 19763a2d0424SChris Cain // error occurs 19773a2d0424SChris Cain return; 19783a2d0424SChris Cain } 19793a2d0424SChris Cain if (subtree.empty()) 19803a2d0424SChris Cain { 19813a2d0424SChris Cain // As noted above, this is an optional interface so just return 19823a2d0424SChris Cain // if there is no instance found 19833a2d0424SChris Cain return; 19843a2d0424SChris Cain } 19853a2d0424SChris Cain if (subtree.size() > 1) 19863a2d0424SChris Cain { 19873a2d0424SChris Cain // More then one PowerMode object is not supported and is an 19883a2d0424SChris Cain // error 19893a2d0424SChris Cain BMCWEB_LOG_DEBUG 19903a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 19913a2d0424SChris Cain << subtree.size(); 19923a2d0424SChris Cain messages::internalError(aResp->res); 19933a2d0424SChris Cain return; 19943a2d0424SChris Cain } 19953a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 19963a2d0424SChris Cain { 19973a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 19983a2d0424SChris Cain messages::internalError(aResp->res); 19993a2d0424SChris Cain return; 20003a2d0424SChris Cain } 20013a2d0424SChris Cain const std::string& path = subtree[0].first; 20023a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 20033a2d0424SChris Cain if (service.empty()) 20043a2d0424SChris Cain { 20053a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 20063a2d0424SChris Cain messages::internalError(aResp->res); 20073a2d0424SChris Cain return; 20083a2d0424SChris Cain } 20093a2d0424SChris Cain // Valid Power Mode object found, now read the current value 20101e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 20111e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 20121e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 20138a592810SEd Tanous [aResp](const boost::system::error_code ec2, 20141e1e598dSJonathan Doman const std::string& pmode) { 20158a592810SEd Tanous if (ec2) 20163a2d0424SChris Cain { 2017002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: " 20188a592810SEd Tanous << ec2; 20193a2d0424SChris Cain messages::internalError(aResp->res); 20203a2d0424SChris Cain return; 20213a2d0424SChris Cain } 20223a2d0424SChris Cain 2023002d39b4SEd Tanous aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2024002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 20253a2d0424SChris Cain 20261e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 20271e1e598dSJonathan Doman translatePowerMode(aResp, pmode); 20281e1e598dSJonathan Doman }); 20293a2d0424SChris Cain }, 20303a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", 20313a2d0424SChris Cain "/xyz/openbmc_project/object_mapper", 20323a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 20333a2d0424SChris Cain std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"}); 20343a2d0424SChris Cain } 20353a2d0424SChris Cain 20363a2d0424SChris Cain /** 20373a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 20383a2d0424SChris Cain * name associated with that string 20393a2d0424SChris Cain * 20403a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20413a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 20423a2d0424SChris Cain * 20433a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 20443a2d0424SChris Cain */ 20453a2d0424SChris Cain inline std::string 20463a2d0424SChris Cain validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 20473a2d0424SChris Cain const std::string& modeString) 20483a2d0424SChris Cain { 20493a2d0424SChris Cain std::string mode; 20503a2d0424SChris Cain 20513a2d0424SChris Cain if (modeString == "Static") 20523a2d0424SChris Cain { 20533a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 20543a2d0424SChris Cain } 20553a2d0424SChris Cain else if (modeString == "MaximumPerformance") 20563a2d0424SChris Cain { 20570fda0f12SGeorge Liu mode = 20580fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 20593a2d0424SChris Cain } 20603a2d0424SChris Cain else if (modeString == "PowerSaving") 20613a2d0424SChris Cain { 20623a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 20633a2d0424SChris Cain } 20643a2d0424SChris Cain else 20653a2d0424SChris Cain { 20663a2d0424SChris Cain messages::propertyValueNotInList(aResp->res, modeString, "PowerMode"); 20673a2d0424SChris Cain } 20683a2d0424SChris Cain return mode; 20693a2d0424SChris Cain } 20703a2d0424SChris Cain 20713a2d0424SChris Cain /** 20723a2d0424SChris Cain * @brief Sets system power mode. 20733a2d0424SChris Cain * 20743a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20753a2d0424SChris Cain * @param[in] pmode System power mode from request. 20763a2d0424SChris Cain * 20773a2d0424SChris Cain * @return None. 20783a2d0424SChris Cain */ 20793a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 20803a2d0424SChris Cain const std::string& pmode) 20813a2d0424SChris Cain { 20823a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 20833a2d0424SChris Cain 20843a2d0424SChris Cain std::string powerMode = validatePowerMode(aResp, pmode); 20853a2d0424SChris Cain if (powerMode.empty()) 20863a2d0424SChris Cain { 20873a2d0424SChris Cain return; 20883a2d0424SChris Cain } 20893a2d0424SChris Cain 20903a2d0424SChris Cain // Get Power Mode object path: 20913a2d0424SChris Cain crow::connections::systemBus->async_method_call( 2092b9d36b47SEd Tanous [aResp, 2093b9d36b47SEd Tanous powerMode](const boost::system::error_code ec, 2094b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 20953a2d0424SChris Cain if (ec) 20963a2d0424SChris Cain { 2097002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2098002d39b4SEd Tanous << ec; 20993a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 21003a2d0424SChris Cain messages::internalError(aResp->res); 21013a2d0424SChris Cain return; 21023a2d0424SChris Cain } 21033a2d0424SChris Cain if (subtree.empty()) 21043a2d0424SChris Cain { 21053a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 21063a2d0424SChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 21073a2d0424SChris Cain "PowerMode"); 21083a2d0424SChris Cain return; 21093a2d0424SChris Cain } 21103a2d0424SChris Cain if (subtree.size() > 1) 21113a2d0424SChris Cain { 21123a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21133a2d0424SChris Cain // error 21143a2d0424SChris Cain BMCWEB_LOG_DEBUG 21153a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 21163a2d0424SChris Cain << subtree.size(); 21173a2d0424SChris Cain messages::internalError(aResp->res); 21183a2d0424SChris Cain return; 21193a2d0424SChris Cain } 21203a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21213a2d0424SChris Cain { 21223a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 21233a2d0424SChris Cain messages::internalError(aResp->res); 21243a2d0424SChris Cain return; 21253a2d0424SChris Cain } 21263a2d0424SChris Cain const std::string& path = subtree[0].first; 21273a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21283a2d0424SChris Cain if (service.empty()) 21293a2d0424SChris Cain { 21303a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 21313a2d0424SChris Cain messages::internalError(aResp->res); 21323a2d0424SChris Cain return; 21333a2d0424SChris Cain } 21343a2d0424SChris Cain 21353a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 21363a2d0424SChris Cain << path; 21373a2d0424SChris Cain 21383a2d0424SChris Cain // Set the Power Mode property 21393a2d0424SChris Cain crow::connections::systemBus->async_method_call( 21408a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 21418a592810SEd Tanous if (ec2) 21423a2d0424SChris Cain { 21433a2d0424SChris Cain messages::internalError(aResp->res); 21443a2d0424SChris Cain return; 21453a2d0424SChris Cain } 21463a2d0424SChris Cain }, 21473a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 21483a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2149168e20c1SEd Tanous dbus::utility::DbusVariantType(powerMode)); 21503a2d0424SChris Cain }, 21513a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", 21523a2d0424SChris Cain "/xyz/openbmc_project/object_mapper", 21533a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 21543a2d0424SChris Cain std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"}); 21553a2d0424SChris Cain } 21563a2d0424SChris Cain 21573a2d0424SChris Cain /** 215851709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 215951709ffdSYong Li * 216051709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 216151709ffdSYong Li * 216251709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 216351709ffdSYong Li * translation cannot be done, returns an empty string. 216451709ffdSYong Li */ 216523a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 216651709ffdSYong Li { 216751709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 216851709ffdSYong Li { 216951709ffdSYong Li return "None"; 217051709ffdSYong Li } 21713174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 217251709ffdSYong Li { 217351709ffdSYong Li return "ResetSystem"; 217451709ffdSYong Li } 21753174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 217651709ffdSYong Li { 217751709ffdSYong Li return "PowerDown"; 217851709ffdSYong Li } 21793174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 218051709ffdSYong Li { 218151709ffdSYong Li return "PowerCycle"; 218251709ffdSYong Li } 218351709ffdSYong Li 218451709ffdSYong Li return ""; 218551709ffdSYong Li } 218651709ffdSYong Li 218751709ffdSYong Li /** 2188c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2189c45f0082SYong Li * 2190c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2191c45f0082SYong Li * 2192c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2193c45f0082SYong Li *If translation cannot be done, returns an empty string. 2194c45f0082SYong Li */ 2195c45f0082SYong Li 219623a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2197c45f0082SYong Li { 2198c45f0082SYong Li if (rfAction == "None") 2199c45f0082SYong Li { 2200c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2201c45f0082SYong Li } 22023174e4dfSEd Tanous if (rfAction == "PowerCycle") 2203c45f0082SYong Li { 2204c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2205c45f0082SYong Li } 22063174e4dfSEd Tanous if (rfAction == "PowerDown") 2207c45f0082SYong Li { 2208c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2209c45f0082SYong Li } 22103174e4dfSEd Tanous if (rfAction == "ResetSystem") 2211c45f0082SYong Li { 2212c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2213c45f0082SYong Li } 2214c45f0082SYong Li 2215c45f0082SYong Li return ""; 2216c45f0082SYong Li } 2217c45f0082SYong Li 2218c45f0082SYong Li /** 221951709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 222051709ffdSYong Li * 222151709ffdSYong Li * @param[in] aResp Shared pointer for completing asynchronous calls. 222251709ffdSYong Li * 222351709ffdSYong Li * @return None. 222451709ffdSYong Li */ 22258d1b46d7Szhanghch05 inline void 22268d1b46d7Szhanghch05 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 222751709ffdSYong Li { 222851709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 2229bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2230bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2231bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2232bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 223351709ffdSYong Li [aResp](const boost::system::error_code ec, 2234b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 223551709ffdSYong Li if (ec) 223651709ffdSYong Li { 223751709ffdSYong Li // watchdog service is stopped 223851709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 223951709ffdSYong Li return; 224051709ffdSYong Li } 224151709ffdSYong Li 224251709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 224351709ffdSYong Li 224451709ffdSYong Li nlohmann::json& hostWatchdogTimer = 224551709ffdSYong Li aResp->res.jsonValue["HostWatchdogTimer"]; 224651709ffdSYong Li 224751709ffdSYong Li // watchdog service is running/enabled 224851709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 224951709ffdSYong Li 2250bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2251bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 225251709ffdSYong Li 2253bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2254bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2255bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2256bc1d29deSKrzysztof Grobelny 2257bc1d29deSKrzysztof Grobelny if (!success) 225851709ffdSYong Li { 225951709ffdSYong Li messages::internalError(aResp->res); 2260601af5edSChicago Duan return; 226151709ffdSYong Li } 226251709ffdSYong Li 2263bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 226451709ffdSYong Li { 2265bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 226651709ffdSYong Li } 226751709ffdSYong Li 2268bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2269bc1d29deSKrzysztof Grobelny { 2270bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 227151709ffdSYong Li if (action.empty()) 227251709ffdSYong Li { 227351709ffdSYong Li messages::internalError(aResp->res); 2274601af5edSChicago Duan return; 227551709ffdSYong Li } 227651709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 227751709ffdSYong Li } 2278bc1d29deSKrzysztof Grobelny }); 227951709ffdSYong Li } 228051709ffdSYong Li 228151709ffdSYong Li /** 2282c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2283c45f0082SYong Li * 2284c45f0082SYong Li * @param[in] aResp Shared pointer for generating response message. 2285c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2286c45f0082SYong Li * RF request. 2287c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2288c45f0082SYong Li * 2289c45f0082SYong Li * @return None. 2290c45f0082SYong Li */ 22918d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 2292c45f0082SYong Li const std::optional<bool> wdtEnable, 2293c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2294c45f0082SYong Li { 2295c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2296c45f0082SYong Li 2297c45f0082SYong Li if (wdtTimeOutAction) 2298c45f0082SYong Li { 2299c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2300c45f0082SYong Li // check if TimeOut Action is Valid 2301c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2302c45f0082SYong Li { 2303c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2304c45f0082SYong Li << *wdtTimeOutAction; 2305c45f0082SYong Li messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction, 2306c45f0082SYong Li "TimeoutAction"); 2307c45f0082SYong Li return; 2308c45f0082SYong Li } 2309c45f0082SYong Li 2310c45f0082SYong Li crow::connections::systemBus->async_method_call( 2311c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2312c45f0082SYong Li if (ec) 2313c45f0082SYong Li { 2314c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2315c45f0082SYong Li messages::internalError(aResp->res); 2316c45f0082SYong Li return; 2317c45f0082SYong Li } 2318c45f0082SYong Li }, 2319c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2320c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2321c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2322c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2323168e20c1SEd Tanous dbus::utility::DbusVariantType(wdtTimeOutActStr)); 2324c45f0082SYong Li } 2325c45f0082SYong Li 2326c45f0082SYong Li if (wdtEnable) 2327c45f0082SYong Li { 2328c45f0082SYong Li crow::connections::systemBus->async_method_call( 2329c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2330c45f0082SYong Li if (ec) 2331c45f0082SYong Li { 2332c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2333c45f0082SYong Li messages::internalError(aResp->res); 2334c45f0082SYong Li return; 2335c45f0082SYong Li } 2336c45f0082SYong Li }, 2337c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2338c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2339c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2340c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2341168e20c1SEd Tanous dbus::utility::DbusVariantType(*wdtEnable)); 2342c45f0082SYong Li } 2343c45f0082SYong Li } 2344c45f0082SYong Li 234537bbf98cSChris Cain /** 234637bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 234737bbf98cSChris Cain * 234837bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 234937bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 235037bbf98cSChris Cain * 235137bbf98cSChris Cain * @return true if successful 235237bbf98cSChris Cain */ 23531e5b7c88SJiaqing Zhao inline bool 23541e5b7c88SJiaqing Zhao parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 23551e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 235637bbf98cSChris Cain { 2357bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2358bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2359bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2360bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2361bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2362bc1d29deSKrzysztof Grobelny 2363bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2364bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2365bc1d29deSKrzysztof Grobelny "EnterUtilizationPercent", enterUtilizationPercent, 2366bc1d29deSKrzysztof Grobelny "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime", 2367bc1d29deSKrzysztof Grobelny exitDwellTime); 2368bc1d29deSKrzysztof Grobelny 2369bc1d29deSKrzysztof Grobelny if (!success) 237037bbf98cSChris Cain { 237137bbf98cSChris Cain return false; 237237bbf98cSChris Cain } 2373bc1d29deSKrzysztof Grobelny 2374bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 237537bbf98cSChris Cain { 2376bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 237737bbf98cSChris Cain } 2378bc1d29deSKrzysztof Grobelny 2379bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 238037bbf98cSChris Cain { 2381bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2382bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 238337bbf98cSChris Cain } 2384bc1d29deSKrzysztof Grobelny 2385bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2386bc1d29deSKrzysztof Grobelny { 2387bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 238837bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 238937bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 239037bbf98cSChris Cain .count(); 239137bbf98cSChris Cain } 2392bc1d29deSKrzysztof Grobelny 2393bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 239437bbf98cSChris Cain { 2395bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2396bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 239737bbf98cSChris Cain } 2398bc1d29deSKrzysztof Grobelny 2399bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 240037bbf98cSChris Cain { 2401bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 240237bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 240337bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 240437bbf98cSChris Cain .count(); 240537bbf98cSChris Cain } 240637bbf98cSChris Cain 240737bbf98cSChris Cain return true; 240837bbf98cSChris Cain } 240937bbf98cSChris Cain 241037bbf98cSChris Cain /** 241137bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 241237bbf98cSChris Cain * 241337bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 241437bbf98cSChris Cain * 241537bbf98cSChris Cain * @return None. 241637bbf98cSChris Cain */ 241737bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 241837bbf98cSChris Cain { 241937bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 242037bbf98cSChris Cain 242137bbf98cSChris Cain // Get IdlePowerSaver object path: 242237bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2423b9d36b47SEd Tanous [aResp](const boost::system::error_code ec, 2424b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 242537bbf98cSChris Cain if (ec) 242637bbf98cSChris Cain { 242737bbf98cSChris Cain BMCWEB_LOG_DEBUG 242837bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 242937bbf98cSChris Cain << ec; 243037bbf98cSChris Cain messages::internalError(aResp->res); 243137bbf98cSChris Cain return; 243237bbf98cSChris Cain } 243337bbf98cSChris Cain if (subtree.empty()) 243437bbf98cSChris Cain { 243537bbf98cSChris Cain // This is an optional interface so just return 243637bbf98cSChris Cain // if there is no instance found 243737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 243837bbf98cSChris Cain return; 243937bbf98cSChris Cain } 244037bbf98cSChris Cain if (subtree.size() > 1) 244137bbf98cSChris Cain { 244237bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 244337bbf98cSChris Cain // is an error 244437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 244537bbf98cSChris Cain "Power.IdlePowerSaver objects: " 244637bbf98cSChris Cain << subtree.size(); 244737bbf98cSChris Cain messages::internalError(aResp->res); 244837bbf98cSChris Cain return; 244937bbf98cSChris Cain } 245037bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 245137bbf98cSChris Cain { 245237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 245337bbf98cSChris Cain messages::internalError(aResp->res); 245437bbf98cSChris Cain return; 245537bbf98cSChris Cain } 245637bbf98cSChris Cain const std::string& path = subtree[0].first; 245737bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 245837bbf98cSChris Cain if (service.empty()) 245937bbf98cSChris Cain { 2460002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 246137bbf98cSChris Cain messages::internalError(aResp->res); 246237bbf98cSChris Cain return; 246337bbf98cSChris Cain } 246437bbf98cSChris Cain 246537bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2466bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2467bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2468bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 24698a592810SEd Tanous [aResp](const boost::system::error_code ec2, 24701e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 24718a592810SEd Tanous if (ec2) 247237bbf98cSChris Cain { 247337bbf98cSChris Cain BMCWEB_LOG_ERROR 24748a592810SEd Tanous << "DBUS response error on IdlePowerSaver GetAll: " << ec2; 247537bbf98cSChris Cain messages::internalError(aResp->res); 247637bbf98cSChris Cain return; 247737bbf98cSChris Cain } 247837bbf98cSChris Cain 2479e05aec50SEd Tanous if (!parseIpsProperties(aResp, properties)) 248037bbf98cSChris Cain { 248137bbf98cSChris Cain messages::internalError(aResp->res); 248237bbf98cSChris Cain return; 248337bbf98cSChris Cain } 2484bc1d29deSKrzysztof Grobelny }); 248537bbf98cSChris Cain }, 248637bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", 248737bbf98cSChris Cain "/xyz/openbmc_project/object_mapper", 248837bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 248937bbf98cSChris Cain std::array<const char*, 1>{ 249037bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver"}); 249137bbf98cSChris Cain 249237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 249337bbf98cSChris Cain } 249437bbf98cSChris Cain 249537bbf98cSChris Cain /** 249637bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 249737bbf98cSChris Cain * 249837bbf98cSChris Cain * @param[in] aResp Shared pointer for generating response message. 249937bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 250037bbf98cSChris Cain * RF request. 250137bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 250237bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 250337bbf98cSChris Cain * before entering idle state. 250437bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 250537bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 250637bbf98cSChris Cain * before exiting idle state 250737bbf98cSChris Cain * 250837bbf98cSChris Cain * @return None. 250937bbf98cSChris Cain */ 251037bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 251137bbf98cSChris Cain const std::optional<bool> ipsEnable, 251237bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 251337bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 251437bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 251537bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 251637bbf98cSChris Cain { 251737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 251837bbf98cSChris Cain 251937bbf98cSChris Cain // Get IdlePowerSaver object path: 252037bbf98cSChris Cain crow::connections::systemBus->async_method_call( 252137bbf98cSChris Cain [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2522b9d36b47SEd Tanous ipsExitTime](const boost::system::error_code ec, 2523b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 252437bbf98cSChris Cain if (ec) 252537bbf98cSChris Cain { 252637bbf98cSChris Cain BMCWEB_LOG_DEBUG 252737bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 252837bbf98cSChris Cain << ec; 252937bbf98cSChris Cain messages::internalError(aResp->res); 253037bbf98cSChris Cain return; 253137bbf98cSChris Cain } 253237bbf98cSChris Cain if (subtree.empty()) 253337bbf98cSChris Cain { 253437bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 253537bbf98cSChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 253637bbf98cSChris Cain "IdlePowerSaver"); 253737bbf98cSChris Cain return; 253837bbf98cSChris Cain } 253937bbf98cSChris Cain if (subtree.size() > 1) 254037bbf98cSChris Cain { 254137bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 254237bbf98cSChris Cain // is an error 25430fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 25440fda0f12SGeorge Liu << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: " 254537bbf98cSChris Cain << subtree.size(); 254637bbf98cSChris Cain messages::internalError(aResp->res); 254737bbf98cSChris Cain return; 254837bbf98cSChris Cain } 254937bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 255037bbf98cSChris Cain { 255137bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 255237bbf98cSChris Cain messages::internalError(aResp->res); 255337bbf98cSChris Cain return; 255437bbf98cSChris Cain } 255537bbf98cSChris Cain const std::string& path = subtree[0].first; 255637bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 255737bbf98cSChris Cain if (service.empty()) 255837bbf98cSChris Cain { 2559002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 256037bbf98cSChris Cain messages::internalError(aResp->res); 256137bbf98cSChris Cain return; 256237bbf98cSChris Cain } 256337bbf98cSChris Cain 256437bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 256537bbf98cSChris Cain // need to be updated 256637bbf98cSChris Cain 256737bbf98cSChris Cain if (ipsEnable) 256837bbf98cSChris Cain { 256937bbf98cSChris Cain crow::connections::systemBus->async_method_call( 25708a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 25718a592810SEd Tanous if (ec2) 257237bbf98cSChris Cain { 25738a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 257437bbf98cSChris Cain messages::internalError(aResp->res); 257537bbf98cSChris Cain return; 257637bbf98cSChris Cain } 257737bbf98cSChris Cain }, 257837bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 2579002d39b4SEd Tanous "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 2580002d39b4SEd Tanous dbus::utility::DbusVariantType(*ipsEnable)); 258137bbf98cSChris Cain } 258237bbf98cSChris Cain if (ipsEnterUtil) 258337bbf98cSChris Cain { 258437bbf98cSChris Cain crow::connections::systemBus->async_method_call( 25858a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 25868a592810SEd Tanous if (ec2) 258737bbf98cSChris Cain { 25888a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 258937bbf98cSChris Cain messages::internalError(aResp->res); 259037bbf98cSChris Cain return; 259137bbf98cSChris Cain } 259237bbf98cSChris Cain }, 259337bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 259437bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 259537bbf98cSChris Cain "EnterUtilizationPercent", 2596168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsEnterUtil)); 259737bbf98cSChris Cain } 259837bbf98cSChris Cain if (ipsEnterTime) 259937bbf98cSChris Cain { 260037bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 260137bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 260237bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26038a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 26048a592810SEd Tanous if (ec2) 260537bbf98cSChris Cain { 26068a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 260737bbf98cSChris Cain messages::internalError(aResp->res); 260837bbf98cSChris Cain return; 260937bbf98cSChris Cain } 261037bbf98cSChris Cain }, 261137bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 261237bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2613168e20c1SEd Tanous "EnterDwellTime", 2614168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 261537bbf98cSChris Cain } 261637bbf98cSChris Cain if (ipsExitUtil) 261737bbf98cSChris Cain { 261837bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26198a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 26208a592810SEd Tanous if (ec2) 262137bbf98cSChris Cain { 26228a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 262337bbf98cSChris Cain messages::internalError(aResp->res); 262437bbf98cSChris Cain return; 262537bbf98cSChris Cain } 262637bbf98cSChris Cain }, 262737bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 262837bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 262937bbf98cSChris Cain "ExitUtilizationPercent", 2630168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsExitUtil)); 263137bbf98cSChris Cain } 263237bbf98cSChris Cain if (ipsExitTime) 263337bbf98cSChris Cain { 263437bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 263537bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 263637bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26378a592810SEd Tanous [aResp](const boost::system::error_code ec2) { 26388a592810SEd Tanous if (ec2) 263937bbf98cSChris Cain { 26408a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 264137bbf98cSChris Cain messages::internalError(aResp->res); 264237bbf98cSChris Cain return; 264337bbf98cSChris Cain } 264437bbf98cSChris Cain }, 264537bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 264637bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2647168e20c1SEd Tanous "ExitDwellTime", 2648168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 264937bbf98cSChris Cain } 265037bbf98cSChris Cain }, 265137bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", 265237bbf98cSChris Cain "/xyz/openbmc_project/object_mapper", 265337bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 265437bbf98cSChris Cain std::array<const char*, 1>{ 265537bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver"}); 265637bbf98cSChris Cain 265737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 265837bbf98cSChris Cain } 265937bbf98cSChris Cain 2660dd60b9edSEd Tanous inline void handleComputerSystemHead( 2661dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2662dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2663dd60b9edSEd Tanous { 2664dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2665dd60b9edSEd Tanous { 2666dd60b9edSEd Tanous return; 2667dd60b9edSEd Tanous } 2668dd60b9edSEd Tanous asyncResp->res.addHeader( 2669dd60b9edSEd Tanous boost::beast::http::field::link, 2670dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2671dd60b9edSEd Tanous } 2672dd60b9edSEd Tanous 2673c45f0082SYong Li /** 2674c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 2675c5b2abe0SLewanczyk, Dawid * Schema 2676c5b2abe0SLewanczyk, Dawid */ 26777e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app) 26781abe55efSEd Tanous { 26797e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2680dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 2681dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 2682dd60b9edSEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 2683dd60b9edSEd Tanous 2684dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2685ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 26867e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 2687f4c99e70SEd Tanous [&app](const crow::Request& req, 26887e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 26893ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2690f4c99e70SEd Tanous { 2691f4c99e70SEd Tanous return; 2692f4c99e70SEd Tanous } 2693dd60b9edSEd Tanous 2694dd60b9edSEd Tanous asyncResp->res.addHeader( 2695dd60b9edSEd Tanous boost::beast::http::field::link, 2696dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 26978d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 26980f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 26998d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 27008d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2701462023adSSunitha Harish 27021e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2703002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 27041e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2705002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 27068a592810SEd Tanous [asyncResp](const boost::system::error_code ec2, 27071e1e598dSJonathan Doman const std::string& /*hostName*/) { 2708002d39b4SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 27092c70f800SEd Tanous ifaceArray = nlohmann::json::array(); 2710002d39b4SEd Tanous auto& count = asyncResp->res.jsonValue["Members@odata.count"]; 27111476687dSEd Tanous 27121476687dSEd Tanous nlohmann::json::object_t system; 27131476687dSEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 27141476687dSEd Tanous ifaceArray.push_back(std::move(system)); 271594bda602STim Lee count = ifaceArray.size(); 27168a592810SEd Tanous if (!ec2) 2717462023adSSunitha Harish { 2718462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 27191476687dSEd Tanous nlohmann::json::object_t hypervisor; 2720002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 27211476687dSEd Tanous ifaceArray.push_back(std::move(hypervisor)); 27222c70f800SEd Tanous count = ifaceArray.size(); 2723cb13a392SEd Tanous } 27241e1e598dSJonathan Doman }); 27257e860f15SJohn Edward Broadbent }); 2726c5b2abe0SLewanczyk, Dawid } 27277e860f15SJohn Edward Broadbent 27287e860f15SJohn Edward Broadbent /** 27297e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 27307e860f15SJohn Edward Broadbent */ 27314f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 27327e860f15SJohn Edward Broadbent { 27337e860f15SJohn Edward Broadbent constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 27347e860f15SJohn Edward Broadbent constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 27357e860f15SJohn Edward Broadbent constexpr char const* interfaceName = 27367e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 27377e860f15SJohn Edward Broadbent constexpr char const* method = "NMI"; 27387e860f15SJohn Edward Broadbent 27397e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 27407e860f15SJohn Edward Broadbent [asyncResp](const boost::system::error_code ec) { 27417e860f15SJohn Edward Broadbent if (ec) 27427e860f15SJohn Edward Broadbent { 27437e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 27447e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 27457e860f15SJohn Edward Broadbent return; 27467e860f15SJohn Edward Broadbent } 27477e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 27487e860f15SJohn Edward Broadbent }, 27497e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 27507e860f15SJohn Edward Broadbent } 2751c5b2abe0SLewanczyk, Dawid 2752c5b2abe0SLewanczyk, Dawid /** 2753cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 2754cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 2755cc340dd9SEd Tanous */ 27567e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app) 2757cc340dd9SEd Tanous { 2758cc340dd9SEd Tanous /** 2759cc340dd9SEd Tanous * Function handles POST method request. 2760cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 2761cc340dd9SEd Tanous */ 27627e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 27637e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/") 2764ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 2765002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 2766002d39b4SEd Tanous [&app](const crow::Request& req, 27677e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 27683ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 276945ca1b86SEd Tanous { 277045ca1b86SEd Tanous return; 277145ca1b86SEd Tanous } 27729712f8acSEd Tanous std::string resetType; 277315ed6780SWilly Tu if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", 27747e860f15SJohn Edward Broadbent resetType)) 2775cc340dd9SEd Tanous { 2776cc340dd9SEd Tanous return; 2777cc340dd9SEd Tanous } 2778cc340dd9SEd Tanous 2779d22c8396SJason M. Bills // Get the command and host vs. chassis 2780cc340dd9SEd Tanous std::string command; 2781543f4400SEd Tanous bool hostCommand = true; 2782d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2783cc340dd9SEd Tanous { 2784cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2785d22c8396SJason M. Bills hostCommand = true; 2786d22c8396SJason M. Bills } 2787d22c8396SJason M. Bills else if (resetType == "ForceOff") 2788d22c8396SJason M. Bills { 2789d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2790d22c8396SJason M. Bills hostCommand = false; 2791d22c8396SJason M. Bills } 2792d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2793d22c8396SJason M. Bills { 279486a0851aSJason M. Bills command = 279586a0851aSJason M. Bills "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 279686a0851aSJason M. Bills hostCommand = true; 2797cc340dd9SEd Tanous } 27989712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2799cc340dd9SEd Tanous { 2800cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2801d22c8396SJason M. Bills hostCommand = true; 2802cc340dd9SEd Tanous } 28039712f8acSEd Tanous else if (resetType == "GracefulRestart") 2804cc340dd9SEd Tanous { 28050fda0f12SGeorge Liu command = 28060fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2807d22c8396SJason M. Bills hostCommand = true; 2808d22c8396SJason M. Bills } 2809d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2810d22c8396SJason M. Bills { 281186a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 281286a0851aSJason M. Bills hostCommand = true; 2813cc340dd9SEd Tanous } 2814bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2815bfd5b826SLakshminarayana R. Kammath { 2816bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2817bfd5b826SLakshminarayana R. Kammath return; 2818bfd5b826SLakshminarayana R. Kammath } 2819cc340dd9SEd Tanous else 2820cc340dd9SEd Tanous { 28218d1b46d7Szhanghch05 messages::actionParameterUnknown(asyncResp->res, "Reset", 28228d1b46d7Szhanghch05 resetType); 2823cc340dd9SEd Tanous return; 2824cc340dd9SEd Tanous } 2825cc340dd9SEd Tanous 2826d22c8396SJason M. Bills if (hostCommand) 2827d22c8396SJason M. Bills { 2828cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 2829d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2830cc340dd9SEd Tanous if (ec) 2831cc340dd9SEd Tanous { 2832cc340dd9SEd Tanous BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 2833002d39b4SEd Tanous if (ec.value() == boost::asio::error::invalid_argument) 2834d22c8396SJason M. Bills { 2835d22c8396SJason M. Bills messages::actionParameterNotSupported( 2836d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2837d22c8396SJason M. Bills } 2838d22c8396SJason M. Bills else 2839d22c8396SJason M. Bills { 2840f12894f8SJason M. Bills messages::internalError(asyncResp->res); 2841d22c8396SJason M. Bills } 2842cc340dd9SEd Tanous return; 2843cc340dd9SEd Tanous } 2844f12894f8SJason M. Bills messages::success(asyncResp->res); 2845cc340dd9SEd Tanous }, 2846cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 2847cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 2848cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 28499712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 2850168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 2851cc340dd9SEd Tanous } 2852d22c8396SJason M. Bills else 2853d22c8396SJason M. Bills { 2854d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 2855d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2856d22c8396SJason M. Bills if (ec) 2857d22c8396SJason M. Bills { 2858d22c8396SJason M. Bills BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 2859002d39b4SEd Tanous if (ec.value() == boost::asio::error::invalid_argument) 2860d22c8396SJason M. Bills { 2861d22c8396SJason M. Bills messages::actionParameterNotSupported( 2862d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2863d22c8396SJason M. Bills } 2864d22c8396SJason M. Bills else 2865d22c8396SJason M. Bills { 2866d22c8396SJason M. Bills messages::internalError(asyncResp->res); 2867d22c8396SJason M. Bills } 2868d22c8396SJason M. Bills return; 2869d22c8396SJason M. Bills } 2870d22c8396SJason M. Bills messages::success(asyncResp->res); 2871d22c8396SJason M. Bills }, 2872d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 2873d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 2874d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 2875002d39b4SEd Tanous "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 2876168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 2877d22c8396SJason M. Bills } 28787e860f15SJohn Edward Broadbent }); 2879d22c8396SJason M. Bills } 2880cc340dd9SEd Tanous 288138c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead( 2882dd60b9edSEd Tanous App& app, const crow::Request& req, 2883dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2884dd60b9edSEd Tanous { 2885dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2886dd60b9edSEd Tanous { 2887dd60b9edSEd Tanous return; 2888dd60b9edSEd Tanous } 2889dd60b9edSEd Tanous 2890dd60b9edSEd Tanous asyncResp->res.addHeader( 2891dd60b9edSEd Tanous boost::beast::http::field::link, 2892dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2893dd60b9edSEd Tanous } 2894dd60b9edSEd Tanous 2895cc340dd9SEd Tanous /** 28966617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 2897c5b2abe0SLewanczyk, Dawid */ 28987e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app) 28991abe55efSEd Tanous { 2900c5b2abe0SLewanczyk, Dawid 2901dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 2902dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystem) 2903dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 2904dd60b9edSEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 2905c5b2abe0SLewanczyk, Dawid /** 2906c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 2907c5b2abe0SLewanczyk, Dawid */ 290822d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 2909ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystem) 2910002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 2911002d39b4SEd Tanous [&app](const crow::Request& req, 291222d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 291322d268cbSEd Tanous const std::string& systemName) { 29143ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 291545ca1b86SEd Tanous { 291645ca1b86SEd Tanous return; 291745ca1b86SEd Tanous } 291822d268cbSEd Tanous if (systemName != "system") 291922d268cbSEd Tanous { 292022d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 292122d268cbSEd Tanous systemName); 292222d268cbSEd Tanous return; 292322d268cbSEd Tanous } 2924dd60b9edSEd Tanous asyncResp->res.addHeader( 2925dd60b9edSEd Tanous boost::beast::http::field::link, 2926dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 29278d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 292837bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 29298d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 29308d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 29318d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 29328d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 29338d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 29348d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 29358d1b46d7Szhanghch05 "Disabled"; 29368d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 29378d1b46d7Szhanghch05 uint64_t(0); 29388d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 29398d1b46d7Szhanghch05 "Disabled"; 2940002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 294104a258f4SEd Tanous 29421476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 29431476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 29441476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 29451476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 29461476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 29471476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 2948029573d4SEd Tanous 2949002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 29501476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 29511476687dSEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] 29521476687dSEd Tanous ["@Redfish.ActionInfo"] = 29531476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 2954c5b2abe0SLewanczyk, Dawid 29551476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 29561476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 29571476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 29581476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 2959c4bf6374SJason M. Bills 29601476687dSEd Tanous nlohmann::json::array_t managedBy; 29611476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 29621476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 2963002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 29641476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 29651476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 29660e8ac5e7SGunnar Mills 29670e8ac5e7SGunnar Mills // Fill in SerialConsole info 2968002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 2969002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = 2970002d39b4SEd Tanous true; 29711476687dSEd Tanous 29720e8ac5e7SGunnar Mills // TODO (Gunnar): Should look for obmc-console-ssh@2200.service 29731476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = 29741476687dSEd Tanous true; 29751476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 29761476687dSEd Tanous asyncResp->res 29771476687dSEd Tanous .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 29781476687dSEd Tanous "Press ~. to exit console"; 29790e8ac5e7SGunnar Mills 29800e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 29810e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 2982002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 2983002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 2984002d39b4SEd Tanous 4; 2985613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 2986613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 29871476687dSEd Tanous 29880e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 29897a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 2990b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 29912ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 2992e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 2993e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 2994b49ac873SJames Feist 2995b49ac873SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 29967a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 29977a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 29987a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 2999914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3000b49ac873SJames Feist if (ec) 3001b49ac873SJames Feist { 3002b49ac873SJames Feist // no inventory 3003b49ac873SJames Feist return; 3004b49ac873SJames Feist } 3005b49ac873SJames Feist 3006914e2d5dSEd Tanous health->inventory = resp; 30077a1dbc48SGeorge Liu }); 3008b49ac873SJames Feist 3009b49ac873SJames Feist health->populate(); 3010b49ac873SJames Feist 3011002d39b4SEd Tanous getMainChassisId(asyncResp, 3012002d39b4SEd Tanous [](const std::string& chassisId, 30138d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3014b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3015b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3016b2c7e208SEd Tanous chassis["@odata.id"] = "/redfish/v1/Chassis/" + chassisId; 3017002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3018c5d03ff4SJennifer Lee }); 3019a3002228SAppaRao Puli 30209f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 30219f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3022a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 30235bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 30246c34de48SEd Tanous getHostState(asyncResp); 3025491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3026978b8803SAndrew Geissler getBootProgress(asyncResp); 3027b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3028adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "PCIeDevices"); 302951709ffdSYong Li getHostWatchdogTimer(asyncResp); 3030c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 30316bd5a8d2SGunnar Mills getAutomaticRetry(asyncResp); 3032c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3033a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3034a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3035a6349918SAppaRao Puli #endif 30361981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 30373a2d0424SChris Cain getPowerMode(asyncResp); 303837bbf98cSChris Cain getIdlePowerSaver(asyncResp); 30397e860f15SJohn Edward Broadbent }); 3040550a6bf8SJiaqing Zhao 304122d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3042ed398213SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 30437e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 304445ca1b86SEd Tanous [&app](const crow::Request& req, 304522d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 304622d268cbSEd Tanous const std::string& systemName) { 30473ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 304845ca1b86SEd Tanous { 304945ca1b86SEd Tanous return; 305045ca1b86SEd Tanous } 305122d268cbSEd Tanous if (systemName != "system") 305222d268cbSEd Tanous { 305322d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 305422d268cbSEd Tanous systemName); 305522d268cbSEd Tanous return; 305622d268cbSEd Tanous } 305722d268cbSEd Tanous 3058dd60b9edSEd Tanous asyncResp->res.addHeader( 3059dd60b9edSEd Tanous boost::beast::http::field::link, 3060dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3061dd60b9edSEd Tanous 30629f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3063cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 306498e386ecSGunnar Mills std::optional<std::string> assetTag; 3065c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 30663a2d0424SChris Cain std::optional<std::string> powerMode; 3067550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3068550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3069550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3070550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3071550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3072550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3073550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 3074550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3075550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3076550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3077550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3078550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3079550a6bf8SJiaqing Zhao 3080550a6bf8SJiaqing Zhao // clang-format off 308115ed6780SWilly Tu if (!json_util::readJsonPatch( 3082550a6bf8SJiaqing Zhao req, asyncResp->res, 3083550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 30847e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3085550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3086550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3087550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3088550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3089550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3090550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3091550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3092550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3093550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3094550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 3095550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3096550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3097550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3098550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3099550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 31006617338dSEd Tanous { 31016617338dSEd Tanous return; 31026617338dSEd Tanous } 3103550a6bf8SJiaqing Zhao // clang-format on 3104491d8ee7SSantosh Puranik 31058d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3106c45f0082SYong Li 310798e386ecSGunnar Mills if (assetTag) 310898e386ecSGunnar Mills { 310998e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 311098e386ecSGunnar Mills } 311198e386ecSGunnar Mills 3112550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3113c45f0082SYong Li { 3114f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3115c45f0082SYong Li } 3116c45f0082SYong Li 3117cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 311869f35306SGunnar Mills { 3119002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3120491d8ee7SSantosh Puranik } 3121550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 312269f35306SGunnar Mills { 3123550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 312469f35306SGunnar Mills } 3125ac7e1e0bSAli Ahmed 3126550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3127ac7e1e0bSAli Ahmed { 3128550a6bf8SJiaqing Zhao setTrustedModuleRequiredToBoot(asyncResp, 3129550a6bf8SJiaqing Zhao *bootTrustedModuleRequired); 313069f35306SGunnar Mills } 3131265c1602SJohnathan Mantey 31329f8bfa7cSGunnar Mills if (locationIndicatorActive) 31339f8bfa7cSGunnar Mills { 3134002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 31359f8bfa7cSGunnar Mills } 31369f8bfa7cSGunnar Mills 31377e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 31387e860f15SJohn Edward Broadbent // passed 31399712f8acSEd Tanous if (indicatorLed) 31406617338dSEd Tanous { 3141f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3142002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3143d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3144d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 31456617338dSEd Tanous } 3146c6a620f2SGeorge Liu 3147c6a620f2SGeorge Liu if (powerRestorePolicy) 3148c6a620f2SGeorge Liu { 31494e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3150c6a620f2SGeorge Liu } 31513a2d0424SChris Cain 31523a2d0424SChris Cain if (powerMode) 31533a2d0424SChris Cain { 31543a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 31553a2d0424SChris Cain } 315637bbf98cSChris Cain 3157550a6bf8SJiaqing Zhao if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || 3158550a6bf8SJiaqing Zhao ipsExitTime) 315937bbf98cSChris Cain { 3160002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3161002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 316237bbf98cSChris Cain } 31637e860f15SJohn Edward Broadbent }); 3164c5b2abe0SLewanczyk, Dawid } 31651cb1a9e6SAppaRao Puli 316638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3167dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 3168dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3169dd60b9edSEd Tanous { 3170dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3171dd60b9edSEd Tanous { 3172dd60b9edSEd Tanous return; 3173dd60b9edSEd Tanous } 3174dd60b9edSEd Tanous asyncResp->res.addHeader( 3175dd60b9edSEd Tanous boost::beast::http::field::link, 3176dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3177dd60b9edSEd Tanous } 3178dd60b9edSEd Tanous 31791cb1a9e6SAppaRao Puli /** 31801cb1a9e6SAppaRao Puli * SystemResetActionInfo derived class for delivering Computer Systems 31811cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 31821cb1a9e6SAppaRao Puli */ 31837e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app) 31841cb1a9e6SAppaRao Puli { 3185dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/") 3186dd60b9edSEd Tanous .privileges(redfish::privileges::headActionInfo) 3187dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3188dd60b9edSEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 31891cb1a9e6SAppaRao Puli /** 31901cb1a9e6SAppaRao Puli * Functions triggers appropriate requests on DBus 31911cb1a9e6SAppaRao Puli */ 319222d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3193ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 31947e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 319545ca1b86SEd Tanous [&app](const crow::Request& req, 319622d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 319722d268cbSEd Tanous const std::string& systemName) { 31983ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 319945ca1b86SEd Tanous { 320045ca1b86SEd Tanous return; 320145ca1b86SEd Tanous } 320222d268cbSEd Tanous if (systemName != "system") 320322d268cbSEd Tanous { 320422d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 320522d268cbSEd Tanous systemName); 320622d268cbSEd Tanous return; 320722d268cbSEd Tanous } 320822d268cbSEd Tanous 3209dd60b9edSEd Tanous asyncResp->res.addHeader( 3210dd60b9edSEd Tanous boost::beast::http::field::link, 3211dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 32121476687dSEd Tanous 32131476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 32141476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 32151476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 32161476687dSEd Tanous "#ActionInfo.v1_1_2.ActionInfo"; 32171476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 32181476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 32193215e700SNan Zhou 32203215e700SNan Zhou nlohmann::json::array_t parameters; 32213215e700SNan Zhou nlohmann::json::object_t parameter; 32223215e700SNan Zhou 32233215e700SNan Zhou parameter["Name"] = "ResetType"; 32243215e700SNan Zhou parameter["Required"] = true; 32253215e700SNan Zhou parameter["DataType"] = "String"; 32263215e700SNan Zhou nlohmann::json::array_t allowableValues; 32273215e700SNan Zhou allowableValues.emplace_back("On"); 32283215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 32293215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 32303215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 32313215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 32323215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 32333215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 32343215e700SNan Zhou allowableValues.emplace_back("Nmi"); 32353215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 32363215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 32373215e700SNan Zhou 32383215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 32397e860f15SJohn Edward Broadbent }); 32401cb1a9e6SAppaRao Puli } 3241c5b2abe0SLewanczyk, Dawid } // namespace redfish 3242