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 18b49ac873SJames Feist #include "health.hpp" 191c8fba97SJames Feist #include "led.hpp" 20f5c9f8bdSJason M. Bills #include "pcie.hpp" 21c5d03ff4SJennifer Lee #include "redfish_util.hpp" 22c5d03ff4SJennifer Lee 237e860f15SJohn Edward Broadbent #include <app.hpp> 249712f8acSEd Tanous #include <boost/container/flat_map.hpp> 25ed398213SEd Tanous #include <registries/privilege_registry.hpp> 26cb7e1e7bSAndrew Geissler #include <utils/fw_utils.hpp> 27c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp> 281214b7e7SGunnar Mills 29abf2add6SEd Tanous #include <variant> 30c5b2abe0SLewanczyk, Dawid 311abe55efSEd Tanous namespace redfish 321abe55efSEd Tanous { 33c5b2abe0SLewanczyk, Dawid 349d3ae10eSAlpana Kumari /** 359d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 369d3ae10eSAlpana Kumari * 379d3ae10eSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 389d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 399d3ae10eSAlpana Kumari * 409d3ae10eSAlpana Kumari * @return None. 419d3ae10eSAlpana Kumari */ 428d1b46d7Szhanghch05 inline void 438d1b46d7Szhanghch05 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 449d3ae10eSAlpana Kumari const std::variant<bool>& dimmState) 459d3ae10eSAlpana Kumari { 469d3ae10eSAlpana Kumari const bool* isDimmFunctional = std::get_if<bool>(&dimmState); 479d3ae10eSAlpana Kumari if (isDimmFunctional == nullptr) 489d3ae10eSAlpana Kumari { 499d3ae10eSAlpana Kumari messages::internalError(aResp->res); 509d3ae10eSAlpana Kumari return; 519d3ae10eSAlpana Kumari } 529d3ae10eSAlpana Kumari BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional; 539d3ae10eSAlpana Kumari 549d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 559d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 569d3ae10eSAlpana Kumari // ENABLED. 579d3ae10eSAlpana Kumari nlohmann::json& prevMemSummary = 589d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 599d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 609d3ae10eSAlpana Kumari { 619d3ae10eSAlpana Kumari if (*isDimmFunctional == true) 629d3ae10eSAlpana Kumari { 639d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 649d3ae10eSAlpana Kumari "Enabled"; 659d3ae10eSAlpana Kumari } 669d3ae10eSAlpana Kumari } 679d3ae10eSAlpana Kumari } 689d3ae10eSAlpana Kumari 6957e8c9beSAlpana Kumari /* 7057e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 7157e8c9beSAlpana Kumari * 7257e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 7357e8c9beSAlpana Kumari * @param[in] cpuPresenceState CPU present or not 7457e8c9beSAlpana Kumari * 7557e8c9beSAlpana Kumari * @return None. 7657e8c9beSAlpana Kumari */ 778d1b46d7Szhanghch05 inline void 788d1b46d7Szhanghch05 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 7957e8c9beSAlpana Kumari const std::variant<bool>& cpuPresenceState) 8057e8c9beSAlpana Kumari { 8157e8c9beSAlpana Kumari const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState); 8257e8c9beSAlpana Kumari 8357e8c9beSAlpana Kumari if (isCpuPresent == nullptr) 8457e8c9beSAlpana Kumari { 8557e8c9beSAlpana Kumari messages::internalError(aResp->res); 8657e8c9beSAlpana Kumari return; 8757e8c9beSAlpana Kumari } 8857e8c9beSAlpana Kumari BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent; 8957e8c9beSAlpana Kumari 9057e8c9beSAlpana Kumari if (*isCpuPresent == true) 9157e8c9beSAlpana Kumari { 92b4b9595aSJames Feist nlohmann::json& procCount = 93b4b9595aSJames Feist aResp->res.jsonValue["ProcessorSummary"]["Count"]; 94b4b9595aSJames Feist auto procCountPtr = 95b4b9595aSJames Feist procCount.get_ptr<nlohmann::json::number_integer_t*>(); 96b4b9595aSJames Feist if (procCountPtr != nullptr) 97b4b9595aSJames Feist { 98b4b9595aSJames Feist // shouldn't be possible to be nullptr 99b4b9595aSJames Feist *procCountPtr += 1; 10057e8c9beSAlpana Kumari } 101b4b9595aSJames Feist } 10257e8c9beSAlpana Kumari } 10357e8c9beSAlpana Kumari 10457e8c9beSAlpana Kumari /* 10557e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 10657e8c9beSAlpana Kumari * CPU Functional State 10757e8c9beSAlpana Kumari * 10857e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 10957e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 11057e8c9beSAlpana Kumari * 11157e8c9beSAlpana Kumari * @return None. 11257e8c9beSAlpana Kumari */ 11323a21a1cSEd Tanous inline void 1148d1b46d7Szhanghch05 modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 11557e8c9beSAlpana Kumari const std::variant<bool>& cpuFunctionalState) 11657e8c9beSAlpana Kumari { 11757e8c9beSAlpana Kumari const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState); 11857e8c9beSAlpana Kumari 11957e8c9beSAlpana Kumari if (isCpuFunctional == nullptr) 12057e8c9beSAlpana Kumari { 12157e8c9beSAlpana Kumari messages::internalError(aResp->res); 12257e8c9beSAlpana Kumari return; 12357e8c9beSAlpana Kumari } 12457e8c9beSAlpana Kumari BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional; 12557e8c9beSAlpana Kumari 12657e8c9beSAlpana Kumari nlohmann::json& prevProcState = 12757e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 12857e8c9beSAlpana Kumari 12957e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 13057e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 13157e8c9beSAlpana Kumari // Functional. 13257e8c9beSAlpana Kumari if (prevProcState == "Disabled") 13357e8c9beSAlpana Kumari { 13457e8c9beSAlpana Kumari if (*isCpuFunctional == true) 13557e8c9beSAlpana Kumari { 13657e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 13757e8c9beSAlpana Kumari "Enabled"; 13857e8c9beSAlpana Kumari } 13957e8c9beSAlpana Kumari } 14057e8c9beSAlpana Kumari } 14157e8c9beSAlpana Kumari 14203fbed92SAli Ahmed inline void getProcessorProperties( 14303fbed92SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service, 14403fbed92SAli Ahmed const std::string& path, 14503fbed92SAli Ahmed const std::vector<std::pair< 14603fbed92SAli Ahmed std::string, std::variant<std::string, uint64_t, uint32_t, uint16_t>>>& 14703fbed92SAli Ahmed properties) 14803fbed92SAli Ahmed { 14903fbed92SAli Ahmed 15003fbed92SAli Ahmed BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties."; 15103fbed92SAli Ahmed 15203fbed92SAli Ahmed auto getCpuPresenceState = 15303fbed92SAli Ahmed [aResp](const boost::system::error_code ec3, 15403fbed92SAli Ahmed const std::variant<bool>& cpuPresenceCheck) { 15503fbed92SAli Ahmed if (ec3) 15603fbed92SAli Ahmed { 15703fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 15803fbed92SAli Ahmed return; 15903fbed92SAli Ahmed } 16003fbed92SAli Ahmed modifyCpuPresenceState(aResp, cpuPresenceCheck); 16103fbed92SAli Ahmed }; 16203fbed92SAli Ahmed 16303fbed92SAli Ahmed auto getCpuFunctionalState = 16403fbed92SAli Ahmed [aResp](const boost::system::error_code ec3, 16503fbed92SAli Ahmed const std::variant<bool>& cpuFunctionalCheck) { 16603fbed92SAli Ahmed if (ec3) 16703fbed92SAli Ahmed { 16803fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 16903fbed92SAli Ahmed return; 17003fbed92SAli Ahmed } 17103fbed92SAli Ahmed modifyCpuFunctionalState(aResp, cpuFunctionalCheck); 17203fbed92SAli Ahmed }; 17303fbed92SAli Ahmed 17403fbed92SAli Ahmed // Get the Presence of CPU 17503fbed92SAli Ahmed crow::connections::systemBus->async_method_call( 17603fbed92SAli Ahmed std::move(getCpuPresenceState), service, path, 17703fbed92SAli Ahmed "org.freedesktop.DBus.Properties", "Get", 17803fbed92SAli Ahmed "xyz.openbmc_project.Inventory.Item", "Present"); 17903fbed92SAli Ahmed 18003fbed92SAli Ahmed // Get the Functional State 18103fbed92SAli Ahmed crow::connections::systemBus->async_method_call( 18203fbed92SAli Ahmed std::move(getCpuFunctionalState), service, path, 18303fbed92SAli Ahmed "org.freedesktop.DBus.Properties", "Get", 18403fbed92SAli Ahmed "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional"); 18503fbed92SAli Ahmed 18603fbed92SAli Ahmed for (const auto& property : properties) 18703fbed92SAli Ahmed { 18803fbed92SAli Ahmed 18903fbed92SAli Ahmed // TODO: Get Model 19003fbed92SAli Ahmed 19103fbed92SAli Ahmed // Get CoreCount 19203fbed92SAli Ahmed if (property.first == "CoreCount") 19303fbed92SAli Ahmed { 19403fbed92SAli Ahmed 19503fbed92SAli Ahmed // Get CPU CoreCount and add it to the total 19603fbed92SAli Ahmed const uint16_t* coreCountVal = 19703fbed92SAli Ahmed std::get_if<uint16_t>(&property.second); 19803fbed92SAli Ahmed 19903fbed92SAli Ahmed if (!coreCountVal) 20003fbed92SAli Ahmed { 20103fbed92SAli Ahmed messages::internalError(aResp->res); 20203fbed92SAli Ahmed return; 20303fbed92SAli Ahmed } 20403fbed92SAli Ahmed 20503fbed92SAli Ahmed nlohmann::json& coreCount = 20603fbed92SAli Ahmed aResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 20703fbed92SAli Ahmed uint64_t* coreCountPtr = coreCount.get_ptr<uint64_t*>(); 20803fbed92SAli Ahmed 20903fbed92SAli Ahmed if (coreCountPtr == nullptr) 21003fbed92SAli Ahmed { 21103fbed92SAli Ahmed coreCount = 0; 21203fbed92SAli Ahmed } 21303fbed92SAli Ahmed else 21403fbed92SAli Ahmed { 21503fbed92SAli Ahmed *coreCountPtr += *coreCountVal; 21603fbed92SAli Ahmed } 21703fbed92SAli Ahmed } 21803fbed92SAli Ahmed } 21903fbed92SAli Ahmed } 22003fbed92SAli Ahmed 22103fbed92SAli Ahmed /* 22203fbed92SAli Ahmed * @brief Get ProcessorSummary fields 22303fbed92SAli Ahmed * 22403fbed92SAli Ahmed * @param[in] aResp Shared pointer for completing asynchronous calls 22503fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 22603fbed92SAli Ahmed * @param[in] path dbus path for Cpu 22703fbed92SAli Ahmed * 22803fbed92SAli Ahmed * @return None. 22903fbed92SAli Ahmed */ 23003fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 23103fbed92SAli Ahmed const std::string& service, 23203fbed92SAli Ahmed const std::string& path) 23303fbed92SAli Ahmed { 23403fbed92SAli Ahmed 23503fbed92SAli Ahmed crow::connections::systemBus->async_method_call( 23603fbed92SAli Ahmed [aResp, service, 23703fbed92SAli Ahmed path](const boost::system::error_code ec2, 23803fbed92SAli Ahmed const std::vector<std::pair< 23903fbed92SAli Ahmed std::string, std::variant<std::string, uint64_t, uint32_t, 24003fbed92SAli Ahmed uint16_t>>>& properties) { 24103fbed92SAli Ahmed if (ec2) 24203fbed92SAli Ahmed { 24303fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 24403fbed92SAli Ahmed messages::internalError(aResp->res); 24503fbed92SAli Ahmed return; 24603fbed92SAli Ahmed } 24703fbed92SAli Ahmed getProcessorProperties(aResp, service, path, properties); 24803fbed92SAli Ahmed }, 24903fbed92SAli Ahmed service, path, "org.freedesktop.DBus.Properties", "GetAll", 25003fbed92SAli Ahmed "xyz.openbmc_project.Inventory.Item.Cpu"); 25103fbed92SAli Ahmed } 25203fbed92SAli Ahmed 25357e8c9beSAlpana Kumari /* 254c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 255c5b2abe0SLewanczyk, Dawid * 256c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 2578f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 258c5b2abe0SLewanczyk, Dawid * 259c5b2abe0SLewanczyk, Dawid * @return None. 260c5b2abe0SLewanczyk, Dawid */ 261b5a76932SEd Tanous inline void 2628d1b46d7Szhanghch05 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 263b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 2641abe55efSEd Tanous { 26555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 2669d3ae10eSAlpana Kumari 26755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 2685bc2dc8eSJames Feist [aResp, systemHealth]( 269c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 270c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 2716c34de48SEd Tanous std::string, 2721214b7e7SGunnar Mills std::vector<std::pair<std::string, std::vector<std::string>>>>>& 2731214b7e7SGunnar Mills subtree) { 2741abe55efSEd Tanous if (ec) 2751abe55efSEd Tanous { 27655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 277f12894f8SJason M. Bills messages::internalError(aResp->res); 278c5b2abe0SLewanczyk, Dawid return; 279c5b2abe0SLewanczyk, Dawid } 280c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 2816c34de48SEd Tanous for (const std::pair<std::string, 2826c34de48SEd Tanous std::vector<std::pair< 2831214b7e7SGunnar Mills std::string, std::vector<std::string>>>>& 2841214b7e7SGunnar Mills object : subtree) 2851abe55efSEd Tanous { 286c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 28755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 2881abe55efSEd Tanous const std::vector< 2891214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 2901214b7e7SGunnar Mills connectionNames = object.second; 2911abe55efSEd Tanous if (connectionNames.size() < 1) 2921abe55efSEd Tanous { 293c5b2abe0SLewanczyk, Dawid continue; 294c5b2abe0SLewanczyk, Dawid } 295029573d4SEd Tanous 2965bc2dc8eSJames Feist auto memoryHealth = std::make_shared<HealthPopulate>( 2975bc2dc8eSJames Feist aResp, aResp->res.jsonValue["MemorySummary"]["Status"]); 2985bc2dc8eSJames Feist 2995bc2dc8eSJames Feist auto cpuHealth = std::make_shared<HealthPopulate>( 3005bc2dc8eSJames Feist aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]); 3015bc2dc8eSJames Feist 3025bc2dc8eSJames Feist systemHealth->children.emplace_back(memoryHealth); 3035bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 3045bc2dc8eSJames Feist 3056c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 3066c34de48SEd Tanous // BiosVer 30704a258f4SEd Tanous for (const auto& connection : connectionNames) 3081abe55efSEd Tanous { 30904a258f4SEd Tanous for (const auto& interfaceName : connection.second) 3101abe55efSEd Tanous { 31104a258f4SEd Tanous if (interfaceName == 31204a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 3131abe55efSEd Tanous { 3141abe55efSEd Tanous BMCWEB_LOG_DEBUG 31504a258f4SEd Tanous << "Found Dimm, now get its properties."; 3169d3ae10eSAlpana Kumari 31755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 3189d3ae10eSAlpana Kumari [aResp, service{connection.first}, 319f23b7296SEd Tanous path](const boost::system::error_code ec2, 3206c34de48SEd Tanous const std::vector< 3211214b7e7SGunnar Mills std::pair<std::string, VariantType>>& 3221214b7e7SGunnar Mills properties) { 323cb13a392SEd Tanous if (ec2) 3241abe55efSEd Tanous { 3251abe55efSEd Tanous BMCWEB_LOG_ERROR 326cb13a392SEd Tanous << "DBUS response error " << ec2; 327f12894f8SJason M. Bills messages::internalError(aResp->res); 328c5b2abe0SLewanczyk, Dawid return; 329c5b2abe0SLewanczyk, Dawid } 3306c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 3316c34de48SEd Tanous << properties.size() 332c5b2abe0SLewanczyk, Dawid << " Dimm properties."; 3339d3ae10eSAlpana Kumari 3349d3ae10eSAlpana Kumari if (properties.size() > 0) 3359d3ae10eSAlpana Kumari { 33604a258f4SEd Tanous for (const std::pair<std::string, 3371214b7e7SGunnar Mills VariantType>& 3381214b7e7SGunnar Mills property : properties) 3391abe55efSEd Tanous { 3405fd7ba65SCheng C Yang if (property.first != 3415fd7ba65SCheng C Yang "MemorySizeInKB") 3421abe55efSEd Tanous { 3435fd7ba65SCheng C Yang continue; 3445fd7ba65SCheng C Yang } 3455fd7ba65SCheng C Yang const uint32_t* value = 3468d78b7a9SPatrick Williams std::get_if<uint32_t>( 3471b6b96c5SEd Tanous &property.second); 3485fd7ba65SCheng C Yang if (value == nullptr) 3491abe55efSEd Tanous { 3505fd7ba65SCheng C Yang BMCWEB_LOG_DEBUG 3515fd7ba65SCheng C Yang << "Find incorrect type of " 3525fd7ba65SCheng C Yang "MemorySize"; 3535fd7ba65SCheng C Yang continue; 3545fd7ba65SCheng C Yang } 3555fd7ba65SCheng C Yang nlohmann::json& totalMemory = 3565fd7ba65SCheng C Yang aResp->res 3575fd7ba65SCheng C Yang .jsonValue["MemorySummar" 3585fd7ba65SCheng C Yang "y"] 3595fd7ba65SCheng C Yang ["TotalSystemMe" 3605fd7ba65SCheng C Yang "moryGiB"]; 3615fd7ba65SCheng C Yang uint64_t* preValue = 3625fd7ba65SCheng C Yang totalMemory 3635fd7ba65SCheng C Yang .get_ptr<uint64_t*>(); 3645fd7ba65SCheng C Yang if (preValue == nullptr) 3655fd7ba65SCheng C Yang { 3665fd7ba65SCheng C Yang continue; 3675fd7ba65SCheng C Yang } 3685fd7ba65SCheng C Yang aResp->res 3695fd7ba65SCheng C Yang .jsonValue["MemorySummary"] 3706c34de48SEd Tanous ["TotalSystemMemoryGi" 3715fd7ba65SCheng C Yang "B"] = 3725fd7ba65SCheng C Yang *value / (1024 * 1024) + 3735fd7ba65SCheng C Yang *preValue; 3745fd7ba65SCheng C Yang aResp->res 3755fd7ba65SCheng C Yang .jsonValue["MemorySummary"] 3769d3ae10eSAlpana Kumari ["Status"]["State"] = 3771abe55efSEd Tanous "Enabled"; 378c5b2abe0SLewanczyk, Dawid } 379c5b2abe0SLewanczyk, Dawid } 3809d3ae10eSAlpana Kumari else 3819d3ae10eSAlpana Kumari { 3829d3ae10eSAlpana Kumari auto getDimmProperties = 3839d3ae10eSAlpana Kumari [aResp]( 3849d3ae10eSAlpana Kumari const boost::system::error_code 385cb13a392SEd Tanous ec3, 3861214b7e7SGunnar Mills const std::variant<bool>& 3871214b7e7SGunnar Mills dimmState) { 388cb13a392SEd Tanous if (ec3) 3899d3ae10eSAlpana Kumari { 3909d3ae10eSAlpana Kumari BMCWEB_LOG_ERROR 3919d3ae10eSAlpana Kumari << "DBUS response " 3929d3ae10eSAlpana Kumari "error " 393cb13a392SEd Tanous << ec3; 3949d3ae10eSAlpana Kumari return; 3959d3ae10eSAlpana Kumari } 3969d3ae10eSAlpana Kumari updateDimmProperties(aResp, 3979d3ae10eSAlpana Kumari dimmState); 3989d3ae10eSAlpana Kumari }; 3999d3ae10eSAlpana Kumari crow::connections::systemBus 4009d3ae10eSAlpana Kumari ->async_method_call( 4019d3ae10eSAlpana Kumari std::move(getDimmProperties), 4029d3ae10eSAlpana Kumari service, path, 4039d3ae10eSAlpana Kumari "org.freedesktop.DBus." 4049d3ae10eSAlpana Kumari "Properties", 4059d3ae10eSAlpana Kumari "Get", 4069d3ae10eSAlpana Kumari "xyz.openbmc_project.State." 4079d3ae10eSAlpana Kumari "Decorator.OperationalStatus", 4089d3ae10eSAlpana Kumari "Functional"); 4099d3ae10eSAlpana Kumari } 410c5b2abe0SLewanczyk, Dawid }, 41104a258f4SEd Tanous connection.first, path, 4126c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 4136c34de48SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm"); 4145bc2dc8eSJames Feist 4155bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 4161abe55efSEd Tanous } 41704a258f4SEd Tanous else if (interfaceName == 41804a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4191abe55efSEd Tanous { 4201abe55efSEd Tanous BMCWEB_LOG_DEBUG 42104a258f4SEd Tanous << "Found Cpu, now get its properties."; 42257e8c9beSAlpana Kumari 42303fbed92SAli Ahmed getProcessorSummary(aResp, connection.first, path); 4245bc2dc8eSJames Feist 4255bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4261abe55efSEd Tanous } 42704a258f4SEd Tanous else if (interfaceName == 42804a258f4SEd Tanous "xyz.openbmc_project.Common.UUID") 4291abe55efSEd Tanous { 4301abe55efSEd Tanous BMCWEB_LOG_DEBUG 43104a258f4SEd Tanous << "Found UUID, now get its properties."; 43255c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 4331214b7e7SGunnar Mills [aResp]( 434cb13a392SEd Tanous const boost::system::error_code ec3, 4356c34de48SEd Tanous const std::vector< 4361214b7e7SGunnar Mills std::pair<std::string, VariantType>>& 4371214b7e7SGunnar Mills properties) { 438cb13a392SEd Tanous if (ec3) 4391abe55efSEd Tanous { 4401abe55efSEd Tanous BMCWEB_LOG_DEBUG 441cb13a392SEd Tanous << "DBUS response error " << ec3; 442f12894f8SJason M. Bills messages::internalError(aResp->res); 443c5b2abe0SLewanczyk, Dawid return; 444c5b2abe0SLewanczyk, Dawid } 4456c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 4466c34de48SEd Tanous << properties.size() 447c5b2abe0SLewanczyk, Dawid << " UUID properties."; 4481abe55efSEd Tanous for (const std::pair<std::string, 4491214b7e7SGunnar Mills VariantType>& 4501214b7e7SGunnar Mills property : properties) 4511abe55efSEd Tanous { 45204a258f4SEd Tanous if (property.first == "UUID") 4531abe55efSEd Tanous { 454c5b2abe0SLewanczyk, Dawid const std::string* value = 4558d78b7a9SPatrick Williams std::get_if<std::string>( 4561b6b96c5SEd Tanous &property.second); 45704a258f4SEd Tanous 4581abe55efSEd Tanous if (value != nullptr) 4591abe55efSEd Tanous { 460029573d4SEd Tanous std::string valueStr = *value; 46104a258f4SEd Tanous if (valueStr.size() == 32) 4621abe55efSEd Tanous { 463029573d4SEd Tanous valueStr.insert(8, 1, '-'); 464029573d4SEd Tanous valueStr.insert(13, 1, '-'); 465029573d4SEd Tanous valueStr.insert(18, 1, '-'); 466029573d4SEd Tanous valueStr.insert(23, 1, '-'); 46704a258f4SEd Tanous } 468029573d4SEd Tanous BMCWEB_LOG_DEBUG << "UUID = " 46904a258f4SEd Tanous << valueStr; 470029573d4SEd Tanous aResp->res.jsonValue["UUID"] = 47104a258f4SEd Tanous valueStr; 472c5b2abe0SLewanczyk, Dawid } 473c5b2abe0SLewanczyk, Dawid } 474c5b2abe0SLewanczyk, Dawid } 475c5b2abe0SLewanczyk, Dawid }, 47604a258f4SEd Tanous connection.first, path, 4776c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 4781abe55efSEd Tanous "xyz.openbmc_project.Common.UUID"); 479c5b2abe0SLewanczyk, Dawid } 480029573d4SEd Tanous else if (interfaceName == 481029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4821abe55efSEd Tanous { 483029573d4SEd Tanous crow::connections::systemBus->async_method_call( 4841214b7e7SGunnar Mills [aResp]( 485cb13a392SEd Tanous const boost::system::error_code ec2, 486029573d4SEd Tanous const std::vector< 4871214b7e7SGunnar Mills std::pair<std::string, VariantType>>& 4881214b7e7SGunnar Mills propertiesList) { 489cb13a392SEd Tanous if (ec2) 490029573d4SEd Tanous { 491e4a4b9a9SJames Feist // doesn't have to include this 492e4a4b9a9SJames Feist // interface 493029573d4SEd Tanous return; 494029573d4SEd Tanous } 495698654b6SGunnar Mills BMCWEB_LOG_DEBUG 496698654b6SGunnar Mills << "Got " << propertiesList.size() 497029573d4SEd Tanous << " properties for system"; 498029573d4SEd Tanous for (const std::pair<std::string, 4991214b7e7SGunnar Mills VariantType>& 5001214b7e7SGunnar Mills property : propertiesList) 501029573d4SEd Tanous { 502fc5afcf9Sbeccabroek const std::string& propertyName = 503fc5afcf9Sbeccabroek property.first; 504fc5afcf9Sbeccabroek if ((propertyName == "PartNumber") || 505fc5afcf9Sbeccabroek (propertyName == "SerialNumber") || 506fc5afcf9Sbeccabroek (propertyName == "Manufacturer") || 5075235d964SSunnySrivastava1984 (propertyName == "Model") || 5085235d964SSunnySrivastava1984 (propertyName == "SubModel")) 509fc5afcf9Sbeccabroek { 510029573d4SEd Tanous const std::string* value = 511fc5afcf9Sbeccabroek std::get_if<std::string>( 512029573d4SEd Tanous &property.second); 513029573d4SEd Tanous if (value != nullptr) 514029573d4SEd Tanous { 515029573d4SEd Tanous aResp->res 516fc5afcf9Sbeccabroek .jsonValue[propertyName] = 517029573d4SEd Tanous *value; 518029573d4SEd Tanous } 519029573d4SEd Tanous } 520fc5afcf9Sbeccabroek } 521c1e236a6SGunnar Mills 522cb7e1e7bSAndrew Geissler // Grab the bios version 523f97ddba7SGunnar Mills fw_util::populateFirmwareInformation( 524cb7e1e7bSAndrew Geissler aResp, fw_util::biosPurpose, 52572d566d9SGunnar Mills "BiosVersion", false); 526029573d4SEd Tanous }, 527029573d4SEd Tanous connection.first, path, 528029573d4SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 529029573d4SEd Tanous "xyz.openbmc_project.Inventory.Decorator." 530029573d4SEd Tanous "Asset"); 531e4a4b9a9SJames Feist 532e4a4b9a9SJames Feist crow::connections::systemBus->async_method_call( 533e4a4b9a9SJames Feist [aResp]( 534cb13a392SEd Tanous const boost::system::error_code ec2, 535e4a4b9a9SJames Feist const std::variant<std::string>& property) { 536cb13a392SEd Tanous if (ec2) 537e4a4b9a9SJames Feist { 538e4a4b9a9SJames Feist // doesn't have to include this 539e4a4b9a9SJames Feist // interface 540e4a4b9a9SJames Feist return; 541e4a4b9a9SJames Feist } 542e4a4b9a9SJames Feist 543e4a4b9a9SJames Feist const std::string* value = 544e4a4b9a9SJames Feist std::get_if<std::string>(&property); 545e4a4b9a9SJames Feist if (value != nullptr) 546e4a4b9a9SJames Feist { 547e4a4b9a9SJames Feist aResp->res.jsonValue["AssetTag"] = 548e4a4b9a9SJames Feist *value; 549e4a4b9a9SJames Feist } 550e4a4b9a9SJames Feist }, 551e4a4b9a9SJames Feist connection.first, path, 552e4a4b9a9SJames Feist "org.freedesktop.DBus.Properties", "Get", 553e4a4b9a9SJames Feist "xyz.openbmc_project.Inventory.Decorator." 554e4a4b9a9SJames Feist "AssetTag", 555e4a4b9a9SJames Feist "AssetTag"); 556029573d4SEd Tanous } 557029573d4SEd Tanous } 558029573d4SEd Tanous } 559c5b2abe0SLewanczyk, Dawid } 560c5b2abe0SLewanczyk, Dawid }, 561c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 562c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 563c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTree", 5646617338dSEd Tanous "/xyz/openbmc_project/inventory", int32_t(0), 5656617338dSEd Tanous std::array<const char*, 5>{ 5666617338dSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset", 5676617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu", 5686617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm", 5696617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.System", 5706617338dSEd Tanous "xyz.openbmc_project.Common.UUID", 5716617338dSEd Tanous }); 572c5b2abe0SLewanczyk, Dawid } 573c5b2abe0SLewanczyk, Dawid 574c5b2abe0SLewanczyk, Dawid /** 575c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 576c5b2abe0SLewanczyk, Dawid * 577c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 578c5b2abe0SLewanczyk, Dawid * 579c5b2abe0SLewanczyk, Dawid * @return None. 580c5b2abe0SLewanczyk, Dawid */ 5818d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 5821abe55efSEd Tanous { 58355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 58455c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 585c5d03ff4SJennifer Lee [aResp](const boost::system::error_code ec, 586abf2add6SEd Tanous const std::variant<std::string>& hostState) { 5871abe55efSEd Tanous if (ec) 5881abe55efSEd Tanous { 58955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 590f12894f8SJason M. Bills messages::internalError(aResp->res); 591c5b2abe0SLewanczyk, Dawid return; 592c5b2abe0SLewanczyk, Dawid } 5936617338dSEd Tanous 594abf2add6SEd Tanous const std::string* s = std::get_if<std::string>(&hostState); 59555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Host state: " << *s; 5966617338dSEd Tanous if (s != nullptr) 5971abe55efSEd Tanous { 598c5b2abe0SLewanczyk, Dawid // Verify Host State 59994732661SAndrew Geissler if (*s == "xyz.openbmc_project.State.Host.HostState.Running") 6001abe55efSEd Tanous { 60155c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 6026617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 6031abe55efSEd Tanous } 60483935af9SAndrew Geissler else if (*s == "xyz.openbmc_project.State.Host.HostState." 6058c888608SGunnar Mills "Quiesced") 6068c888608SGunnar Mills { 6078c888608SGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 6088c888608SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6098c888608SGunnar Mills } 6108c888608SGunnar Mills else if (*s == "xyz.openbmc_project.State.Host.HostState." 61183935af9SAndrew Geissler "DiagnosticMode") 61283935af9SAndrew Geissler { 61383935af9SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 61483935af9SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "InTest"; 61583935af9SAndrew Geissler } 6161a2a1437SAndrew Geissler else if (*s == "xyz.openbmc_project.State.Host.HostState." 6171a2a1437SAndrew Geissler "TransitioningToRunning") 6181a2a1437SAndrew Geissler { 6191a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOn"; 62015c27bf8SNoah Brewer aResp->res.jsonValue["Status"]["State"] = "Starting"; 6211a2a1437SAndrew Geissler } 6221a2a1437SAndrew Geissler else if (*s == "xyz.openbmc_project.State.Host.HostState." 6231a2a1437SAndrew Geissler "TransitioningToOff") 6241a2a1437SAndrew Geissler { 6251a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOff"; 6261a2a1437SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Disabled"; 6271a2a1437SAndrew Geissler } 6281abe55efSEd Tanous else 6291abe55efSEd Tanous { 63055c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 6316617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 632c5b2abe0SLewanczyk, Dawid } 633c5b2abe0SLewanczyk, Dawid } 634c5b2abe0SLewanczyk, Dawid }, 6356c34de48SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 6366617338dSEd Tanous "org.freedesktop.DBus.Properties", "Get", 6376617338dSEd Tanous "xyz.openbmc_project.State.Host", "CurrentHostState"); 638c5b2abe0SLewanczyk, Dawid } 639c5b2abe0SLewanczyk, Dawid 640c5b2abe0SLewanczyk, Dawid /** 641786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 642491d8ee7SSantosh Puranik * 643491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 644491d8ee7SSantosh Puranik * 645491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 646491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 647491d8ee7SSantosh Puranik */ 64823a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 649491d8ee7SSantosh Puranik { 650491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 651491d8ee7SSantosh Puranik { 652491d8ee7SSantosh Puranik return "None"; 653491d8ee7SSantosh Puranik } 6543174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 655491d8ee7SSantosh Puranik { 656491d8ee7SSantosh Puranik return "Hdd"; 657491d8ee7SSantosh Puranik } 6583174e4dfSEd Tanous if (dbusSource == 659a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 660491d8ee7SSantosh Puranik { 661491d8ee7SSantosh Puranik return "Cd"; 662491d8ee7SSantosh Puranik } 6633174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 664491d8ee7SSantosh Puranik { 665491d8ee7SSantosh Puranik return "Pxe"; 666491d8ee7SSantosh Puranik } 6673174e4dfSEd Tanous if (dbusSource == 668944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6699f16b2c1SJennifer Lee { 6709f16b2c1SJennifer Lee return "Usb"; 6719f16b2c1SJennifer Lee } 672491d8ee7SSantosh Puranik return ""; 673491d8ee7SSantosh Puranik } 674491d8ee7SSantosh Puranik 675491d8ee7SSantosh Puranik /** 676cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 677cd9a4666SKonstantin Aladyshev * 678cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 679cd9a4666SKonstantin Aladyshev * 680cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 681cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 682cd9a4666SKonstantin Aladyshev */ 683cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 684cd9a4666SKonstantin Aladyshev { 685cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 686cd9a4666SKonstantin Aladyshev { 687cd9a4666SKonstantin Aladyshev return "Legacy"; 688cd9a4666SKonstantin Aladyshev } 689cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 690cd9a4666SKonstantin Aladyshev { 691cd9a4666SKonstantin Aladyshev return "UEFI"; 692cd9a4666SKonstantin Aladyshev } 693cd9a4666SKonstantin Aladyshev return ""; 694cd9a4666SKonstantin Aladyshev } 695cd9a4666SKonstantin Aladyshev 696cd9a4666SKonstantin Aladyshev /** 697786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 698491d8ee7SSantosh Puranik * 699491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 700491d8ee7SSantosh Puranik * 701491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 702491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 703491d8ee7SSantosh Puranik */ 70423a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 705491d8ee7SSantosh Puranik { 706491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 707491d8ee7SSantosh Puranik { 708491d8ee7SSantosh Puranik return "None"; 709491d8ee7SSantosh Puranik } 7103174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 711491d8ee7SSantosh Puranik { 712491d8ee7SSantosh Puranik return "Diags"; 713491d8ee7SSantosh Puranik } 7143174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 715491d8ee7SSantosh Puranik { 716491d8ee7SSantosh Puranik return "BiosSetup"; 717491d8ee7SSantosh Puranik } 718491d8ee7SSantosh Puranik return ""; 719491d8ee7SSantosh Puranik } 720491d8ee7SSantosh Puranik 721491d8ee7SSantosh Puranik /** 722786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 723491d8ee7SSantosh Puranik * 724491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 725944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 726944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 727491d8ee7SSantosh Puranik * 728944ffaf9SJohnathan Mantey * @return Integer error code. 729491d8ee7SSantosh Puranik */ 7308d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 731944ffaf9SJohnathan Mantey const std::string& rfSource, 732944ffaf9SJohnathan Mantey std::string& bootSource, std::string& bootMode) 733491d8ee7SSantosh Puranik { 734c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 735c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 736944ffaf9SJohnathan Mantey 737491d8ee7SSantosh Puranik if (rfSource == "None") 738491d8ee7SSantosh Puranik { 739944ffaf9SJohnathan Mantey return 0; 740491d8ee7SSantosh Puranik } 7413174e4dfSEd Tanous if (rfSource == "Pxe") 742491d8ee7SSantosh Puranik { 743944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 744944ffaf9SJohnathan Mantey } 745944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 746944ffaf9SJohnathan Mantey { 747944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 748944ffaf9SJohnathan Mantey } 749944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 750944ffaf9SJohnathan Mantey { 751944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 752944ffaf9SJohnathan Mantey } 753944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 754944ffaf9SJohnathan Mantey { 755944ffaf9SJohnathan Mantey bootSource = 756944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 757944ffaf9SJohnathan Mantey } 758944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 759944ffaf9SJohnathan Mantey { 760944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 761491d8ee7SSantosh Puranik } 7629f16b2c1SJennifer Lee else if (rfSource == "Usb") 7639f16b2c1SJennifer Lee { 764944ffaf9SJohnathan Mantey bootSource = 765944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 7669f16b2c1SJennifer Lee } 767491d8ee7SSantosh Puranik else 768491d8ee7SSantosh Puranik { 769944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "Invalid property value for " 770944ffaf9SJohnathan Mantey "BootSourceOverrideTarget: " 771944ffaf9SJohnathan Mantey << bootSource; 772944ffaf9SJohnathan Mantey messages::propertyValueNotInList(aResp->res, rfSource, 773944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 774944ffaf9SJohnathan Mantey return -1; 775491d8ee7SSantosh Puranik } 776944ffaf9SJohnathan Mantey return 0; 777491d8ee7SSantosh Puranik } 7781981771bSAli Ahmed 779978b8803SAndrew Geissler /** 780978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 781978b8803SAndrew Geissler * 782978b8803SAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 783978b8803SAndrew Geissler * 784978b8803SAndrew Geissler * @return None. 785978b8803SAndrew Geissler */ 7868d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 787978b8803SAndrew Geissler { 788978b8803SAndrew Geissler crow::connections::systemBus->async_method_call( 789978b8803SAndrew Geissler [aResp](const boost::system::error_code ec, 790978b8803SAndrew Geissler const std::variant<std::string>& bootProgress) { 791978b8803SAndrew Geissler if (ec) 792978b8803SAndrew Geissler { 793978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 794978b8803SAndrew Geissler // not found 795978b8803SAndrew Geissler return; 796978b8803SAndrew Geissler } 797978b8803SAndrew Geissler 798978b8803SAndrew Geissler const std::string* bootProgressStr = 799978b8803SAndrew Geissler std::get_if<std::string>(&bootProgress); 800978b8803SAndrew Geissler 801978b8803SAndrew Geissler if (!bootProgressStr) 802978b8803SAndrew Geissler { 803978b8803SAndrew Geissler // Interface implemented but property not found, return error 804978b8803SAndrew Geissler // for that 805978b8803SAndrew Geissler messages::internalError(aResp->res); 806978b8803SAndrew Geissler return; 807978b8803SAndrew Geissler } 808978b8803SAndrew Geissler 809978b8803SAndrew Geissler BMCWEB_LOG_DEBUG << "Boot Progress: " << *bootProgressStr; 810978b8803SAndrew Geissler 811978b8803SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 812978b8803SAndrew Geissler // enum 813978b8803SAndrew Geissler std::string rfBpLastState = "None"; 814978b8803SAndrew Geissler if (*bootProgressStr == "xyz.openbmc_project.State.Boot.Progress." 815978b8803SAndrew Geissler "ProgressStages.Unspecified") 816978b8803SAndrew Geissler { 817978b8803SAndrew Geissler rfBpLastState = "None"; 818978b8803SAndrew Geissler } 819978b8803SAndrew Geissler else if (*bootProgressStr == 820978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 821978b8803SAndrew Geissler "PrimaryProcInit") 822978b8803SAndrew Geissler { 823978b8803SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 824978b8803SAndrew Geissler } 825978b8803SAndrew Geissler else if (*bootProgressStr == 826978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 827978b8803SAndrew Geissler "BusInit") 828978b8803SAndrew Geissler { 829978b8803SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 830978b8803SAndrew Geissler } 831978b8803SAndrew Geissler else if (*bootProgressStr == 832978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 833978b8803SAndrew Geissler "MemoryInit") 834978b8803SAndrew Geissler { 835978b8803SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 836978b8803SAndrew Geissler } 837978b8803SAndrew Geissler else if (*bootProgressStr == 838978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 839978b8803SAndrew Geissler "SecondaryProcInit") 840978b8803SAndrew Geissler { 841978b8803SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 842978b8803SAndrew Geissler } 843978b8803SAndrew Geissler else if (*bootProgressStr == 844978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 845978b8803SAndrew Geissler "PCIInit") 846978b8803SAndrew Geissler { 847978b8803SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 848978b8803SAndrew Geissler } 849978b8803SAndrew Geissler else if (*bootProgressStr == 850978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 851978b8803SAndrew Geissler "SystemInitComplete") 852978b8803SAndrew Geissler { 853978b8803SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 854978b8803SAndrew Geissler } 855978b8803SAndrew Geissler else if (*bootProgressStr == 856978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 857978b8803SAndrew Geissler "OSStart") 858978b8803SAndrew Geissler { 859978b8803SAndrew Geissler rfBpLastState = "OSBootStarted"; 860978b8803SAndrew Geissler } 861978b8803SAndrew Geissler else if (*bootProgressStr == 862978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 863978b8803SAndrew Geissler "OSRunning") 864978b8803SAndrew Geissler { 865978b8803SAndrew Geissler rfBpLastState = "OSRunning"; 866978b8803SAndrew Geissler } 867978b8803SAndrew Geissler else 868978b8803SAndrew Geissler { 869978b8803SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 870978b8803SAndrew Geissler << *bootProgressStr; 871978b8803SAndrew Geissler // Just return the default 872978b8803SAndrew Geissler } 873978b8803SAndrew Geissler 874978b8803SAndrew Geissler aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState; 875978b8803SAndrew Geissler }, 876978b8803SAndrew Geissler "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 877978b8803SAndrew Geissler "org.freedesktop.DBus.Properties", "Get", 878978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress", "BootProgress"); 879978b8803SAndrew Geissler } 880491d8ee7SSantosh Puranik 881491d8ee7SSantosh Puranik /** 882c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 883cd9a4666SKonstantin Aladyshev * 884cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 885cd9a4666SKonstantin Aladyshev * 886cd9a4666SKonstantin Aladyshev * @return None. 887cd9a4666SKonstantin Aladyshev */ 888cd9a4666SKonstantin Aladyshev 889c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 890cd9a4666SKonstantin Aladyshev { 891cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 892cd9a4666SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 893cd9a4666SKonstantin Aladyshev const std::variant<std::string>& bootType) { 894cd9a4666SKonstantin Aladyshev if (ec) 895cd9a4666SKonstantin Aladyshev { 896cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 897cd9a4666SKonstantin Aladyshev return; 898cd9a4666SKonstantin Aladyshev } 899cd9a4666SKonstantin Aladyshev 900cd9a4666SKonstantin Aladyshev const std::string* bootTypeStr = 901cd9a4666SKonstantin Aladyshev std::get_if<std::string>(&bootType); 902cd9a4666SKonstantin Aladyshev 903cd9a4666SKonstantin Aladyshev if (!bootTypeStr) 904cd9a4666SKonstantin Aladyshev { 905cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 906cd9a4666SKonstantin Aladyshev return; 907cd9a4666SKonstantin Aladyshev } 908cd9a4666SKonstantin Aladyshev 909cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootTypeStr; 910cd9a4666SKonstantin Aladyshev 911cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode@Redfish." 912cd9a4666SKonstantin Aladyshev "AllowableValues"] = {"Legacy", 913cd9a4666SKonstantin Aladyshev "UEFI"}; 914cd9a4666SKonstantin Aladyshev 915cd9a4666SKonstantin Aladyshev auto rfType = dbusToRfBootType(*bootTypeStr); 916cd9a4666SKonstantin Aladyshev if (rfType.empty()) 917cd9a4666SKonstantin Aladyshev { 918cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 919cd9a4666SKonstantin Aladyshev return; 920cd9a4666SKonstantin Aladyshev } 921cd9a4666SKonstantin Aladyshev 922cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 923cd9a4666SKonstantin Aladyshev }, 924c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 925c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 926cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Get", 927cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType"); 928cd9a4666SKonstantin Aladyshev } 929cd9a4666SKonstantin Aladyshev 930cd9a4666SKonstantin Aladyshev /** 931c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 932491d8ee7SSantosh Puranik * 933491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 934491d8ee7SSantosh Puranik * 935491d8ee7SSantosh Puranik * @return None. 936491d8ee7SSantosh Puranik */ 937c21865c4SKonstantin Aladyshev 938c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 939491d8ee7SSantosh Puranik { 940491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 941c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 942491d8ee7SSantosh Puranik const std::variant<std::string>& bootMode) { 943491d8ee7SSantosh Puranik if (ec) 944491d8ee7SSantosh Puranik { 945491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 946491d8ee7SSantosh Puranik messages::internalError(aResp->res); 947491d8ee7SSantosh Puranik return; 948491d8ee7SSantosh Puranik } 949491d8ee7SSantosh Puranik 950491d8ee7SSantosh Puranik const std::string* bootModeStr = 951491d8ee7SSantosh Puranik std::get_if<std::string>(&bootMode); 952491d8ee7SSantosh Puranik 953491d8ee7SSantosh Puranik if (!bootModeStr) 954491d8ee7SSantosh Puranik { 955491d8ee7SSantosh Puranik messages::internalError(aResp->res); 956491d8ee7SSantosh Puranik return; 957491d8ee7SSantosh Puranik } 958491d8ee7SSantosh Puranik 959491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr; 960491d8ee7SSantosh Puranik 961491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish." 962491d8ee7SSantosh Puranik "AllowableValues"] = { 963944ffaf9SJohnathan Mantey "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 964491d8ee7SSantosh Puranik 965491d8ee7SSantosh Puranik if (*bootModeStr != 966491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 967491d8ee7SSantosh Puranik { 968491d8ee7SSantosh Puranik auto rfMode = dbusToRfBootMode(*bootModeStr); 969491d8ee7SSantosh Puranik if (!rfMode.empty()) 970491d8ee7SSantosh Puranik { 971491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 972491d8ee7SSantosh Puranik rfMode; 973491d8ee7SSantosh Puranik } 974491d8ee7SSantosh Puranik } 975491d8ee7SSantosh Puranik }, 976c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 977c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 978491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Get", 979491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode"); 980491d8ee7SSantosh Puranik } 981491d8ee7SSantosh Puranik 982491d8ee7SSantosh Puranik /** 983c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 984491d8ee7SSantosh Puranik * 985491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 986491d8ee7SSantosh Puranik * 987491d8ee7SSantosh Puranik * @return None. 988491d8ee7SSantosh Puranik */ 989c21865c4SKonstantin Aladyshev 990c21865c4SKonstantin Aladyshev inline void 991c21865c4SKonstantin Aladyshev getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 992491d8ee7SSantosh Puranik { 993491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 994c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 995491d8ee7SSantosh Puranik const std::variant<std::string>& bootSource) { 996491d8ee7SSantosh Puranik if (ec) 997491d8ee7SSantosh Puranik { 998491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 999491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1000491d8ee7SSantosh Puranik return; 1001491d8ee7SSantosh Puranik } 1002491d8ee7SSantosh Puranik 1003491d8ee7SSantosh Puranik const std::string* bootSourceStr = 1004491d8ee7SSantosh Puranik std::get_if<std::string>(&bootSource); 1005491d8ee7SSantosh Puranik 1006491d8ee7SSantosh Puranik if (!bootSourceStr) 1007491d8ee7SSantosh Puranik { 1008491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1009491d8ee7SSantosh Puranik return; 1010491d8ee7SSantosh Puranik } 1011491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr; 1012491d8ee7SSantosh Puranik 1013491d8ee7SSantosh Puranik auto rfSource = dbusToRfBootSource(*bootSourceStr); 1014491d8ee7SSantosh Puranik if (!rfSource.empty()) 1015491d8ee7SSantosh Puranik { 1016491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1017491d8ee7SSantosh Puranik rfSource; 1018491d8ee7SSantosh Puranik } 1019cd9a4666SKonstantin Aladyshev 1020cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1021cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1022c21865c4SKonstantin Aladyshev getBootOverrideMode(aResp); 1023491d8ee7SSantosh Puranik }, 1024c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1025c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1026491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Get", 1027491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource"); 1028491d8ee7SSantosh Puranik } 1029491d8ee7SSantosh Puranik 1030491d8ee7SSantosh Puranik /** 1031c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1032c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1033c21865c4SKonstantin Aladyshev * state 1034491d8ee7SSantosh Puranik * 1035491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1036491d8ee7SSantosh Puranik * 1037491d8ee7SSantosh Puranik * @return None. 1038491d8ee7SSantosh Puranik */ 1039491d8ee7SSantosh Puranik 1040c21865c4SKonstantin Aladyshev inline void 1041c21865c4SKonstantin Aladyshev processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1042c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1043c21865c4SKonstantin Aladyshev { 1044c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1045c21865c4SKonstantin Aladyshev { 1046c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; 1047c21865c4SKonstantin Aladyshev return; 1048c21865c4SKonstantin Aladyshev } 1049c21865c4SKonstantin Aladyshev 1050c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1051c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 1052491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1053c5d03ff4SJennifer Lee [aResp](const boost::system::error_code ec, 105419bd78d9SPatrick Williams const std::variant<bool>& oneTime) { 1055491d8ee7SSantosh Puranik if (ec) 1056491d8ee7SSantosh Puranik { 1057491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1058c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1059491d8ee7SSantosh Puranik return; 1060491d8ee7SSantosh Puranik } 1061491d8ee7SSantosh Puranik 1062491d8ee7SSantosh Puranik const bool* oneTimePtr = std::get_if<bool>(&oneTime); 1063491d8ee7SSantosh Puranik 1064491d8ee7SSantosh Puranik if (!oneTimePtr) 1065491d8ee7SSantosh Puranik { 1066491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1067491d8ee7SSantosh Puranik return; 1068491d8ee7SSantosh Puranik } 1069c21865c4SKonstantin Aladyshev 1070c21865c4SKonstantin Aladyshev bool oneTimeSetting = *oneTimePtr; 1071c21865c4SKonstantin Aladyshev 1072c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1073c21865c4SKonstantin Aladyshev { 1074c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1075c21865c4SKonstantin Aladyshev "Once"; 1076c21865c4SKonstantin Aladyshev } 1077c21865c4SKonstantin Aladyshev else 1078c21865c4SKonstantin Aladyshev { 1079c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1080c21865c4SKonstantin Aladyshev "Continuous"; 1081c21865c4SKonstantin Aladyshev } 1082491d8ee7SSantosh Puranik }, 1083491d8ee7SSantosh Puranik "xyz.openbmc_project.Settings", 1084491d8ee7SSantosh Puranik "/xyz/openbmc_project/control/host0/boot/one_time", 1085491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Get", 1086491d8ee7SSantosh Puranik "xyz.openbmc_project.Object.Enable", "Enabled"); 1087491d8ee7SSantosh Puranik } 1088491d8ee7SSantosh Puranik 1089491d8ee7SSantosh Puranik /** 1090c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1091c21865c4SKonstantin Aladyshev * 1092c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1093c21865c4SKonstantin Aladyshev * 1094c21865c4SKonstantin Aladyshev * @return None. 1095c21865c4SKonstantin Aladyshev */ 1096c21865c4SKonstantin Aladyshev 1097c21865c4SKonstantin Aladyshev inline void 1098c21865c4SKonstantin Aladyshev getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1099c21865c4SKonstantin Aladyshev { 1100c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1101c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 1102c21865c4SKonstantin Aladyshev const std::variant<bool>& bootOverrideEnable) { 1103c21865c4SKonstantin Aladyshev if (ec) 1104c21865c4SKonstantin Aladyshev { 1105c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1106c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1107c21865c4SKonstantin Aladyshev return; 1108c21865c4SKonstantin Aladyshev } 1109c21865c4SKonstantin Aladyshev 1110c21865c4SKonstantin Aladyshev const bool* bootOverrideEnablePtr = 1111c21865c4SKonstantin Aladyshev std::get_if<bool>(&bootOverrideEnable); 1112c21865c4SKonstantin Aladyshev 1113c21865c4SKonstantin Aladyshev if (!bootOverrideEnablePtr) 1114c21865c4SKonstantin Aladyshev { 1115c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1116c21865c4SKonstantin Aladyshev return; 1117c21865c4SKonstantin Aladyshev } 1118c21865c4SKonstantin Aladyshev 1119c21865c4SKonstantin Aladyshev processBootOverrideEnable(aResp, *bootOverrideEnablePtr); 1120c21865c4SKonstantin Aladyshev }, 1121c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1122c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1123c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Get", 1124c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled"); 1125c21865c4SKonstantin Aladyshev } 1126c21865c4SKonstantin Aladyshev 1127c21865c4SKonstantin Aladyshev /** 1128c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1129c21865c4SKonstantin Aladyshev * 1130c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1131c21865c4SKonstantin Aladyshev * 1132c21865c4SKonstantin Aladyshev * @return None. 1133c21865c4SKonstantin Aladyshev */ 1134c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1135c21865c4SKonstantin Aladyshev { 1136c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1137c21865c4SKonstantin Aladyshev 1138c21865c4SKonstantin Aladyshev getBootOverrideSource(aResp); 1139c21865c4SKonstantin Aladyshev getBootOverrideType(aResp); 1140c21865c4SKonstantin Aladyshev getBootOverrideEnable(aResp); 1141c21865c4SKonstantin Aladyshev } 1142c21865c4SKonstantin Aladyshev 1143c21865c4SKonstantin Aladyshev /** 1144c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1145c0557e1aSGunnar Mills * 1146c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1147c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1148c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1149c0557e1aSGunnar Mills * last power operation time. 1150c0557e1aSGunnar Mills * 1151c0557e1aSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 1152c0557e1aSGunnar Mills * 1153c0557e1aSGunnar Mills * @return None. 1154c0557e1aSGunnar Mills */ 11558d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1156c0557e1aSGunnar Mills { 1157c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1158c0557e1aSGunnar Mills 1159c0557e1aSGunnar Mills crow::connections::systemBus->async_method_call( 1160c0557e1aSGunnar Mills [aResp](const boost::system::error_code ec, 1161c0557e1aSGunnar Mills std::variant<uint64_t>& lastResetTime) { 1162c0557e1aSGunnar Mills if (ec) 1163c0557e1aSGunnar Mills { 1164c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1165c0557e1aSGunnar Mills return; 1166c0557e1aSGunnar Mills } 1167c0557e1aSGunnar Mills 1168c0557e1aSGunnar Mills const uint64_t* lastResetTimePtr = 1169c0557e1aSGunnar Mills std::get_if<uint64_t>(&lastResetTime); 1170c0557e1aSGunnar Mills 1171c0557e1aSGunnar Mills if (!lastResetTimePtr) 1172c0557e1aSGunnar Mills { 1173c0557e1aSGunnar Mills messages::internalError(aResp->res); 1174c0557e1aSGunnar Mills return; 1175c0557e1aSGunnar Mills } 1176c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1177c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 1178c0557e1aSGunnar Mills time_t lastResetTimeStamp = 1179c0557e1aSGunnar Mills static_cast<time_t>(*lastResetTimePtr / 1000); 1180c0557e1aSGunnar Mills 1181c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1182c0557e1aSGunnar Mills aResp->res.jsonValue["LastResetTime"] = 1183c0557e1aSGunnar Mills crow::utility::getDateTime(lastResetTimeStamp); 1184c0557e1aSGunnar Mills }, 1185c0557e1aSGunnar Mills "xyz.openbmc_project.State.Chassis", 1186c0557e1aSGunnar Mills "/xyz/openbmc_project/state/chassis0", 1187c0557e1aSGunnar Mills "org.freedesktop.DBus.Properties", "Get", 1188c0557e1aSGunnar Mills "xyz.openbmc_project.State.Chassis", "LastStateChangeTime"); 1189c0557e1aSGunnar Mills } 1190c0557e1aSGunnar Mills 1191c0557e1aSGunnar Mills /** 11926bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 11936bd5a8d2SGunnar Mills * 11946bd5a8d2SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 11956bd5a8d2SGunnar Mills * 11966bd5a8d2SGunnar Mills * @return None. 11976bd5a8d2SGunnar Mills */ 11988d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 11996bd5a8d2SGunnar Mills { 12006bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 12016bd5a8d2SGunnar Mills 12026bd5a8d2SGunnar Mills crow::connections::systemBus->async_method_call( 12036bd5a8d2SGunnar Mills [aResp](const boost::system::error_code ec, 12046bd5a8d2SGunnar Mills std::variant<bool>& autoRebootEnabled) { 12056bd5a8d2SGunnar Mills if (ec) 12066bd5a8d2SGunnar Mills { 12076bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 12086bd5a8d2SGunnar Mills return; 12096bd5a8d2SGunnar Mills } 12106bd5a8d2SGunnar Mills 12116bd5a8d2SGunnar Mills const bool* autoRebootEnabledPtr = 12126bd5a8d2SGunnar Mills std::get_if<bool>(&autoRebootEnabled); 12136bd5a8d2SGunnar Mills 12146bd5a8d2SGunnar Mills if (!autoRebootEnabledPtr) 12156bd5a8d2SGunnar Mills { 12166bd5a8d2SGunnar Mills messages::internalError(aResp->res); 12176bd5a8d2SGunnar Mills return; 12186bd5a8d2SGunnar Mills } 12196bd5a8d2SGunnar Mills 12206bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr; 12216bd5a8d2SGunnar Mills if (*autoRebootEnabledPtr == true) 12226bd5a8d2SGunnar Mills { 12236bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12246bd5a8d2SGunnar Mills "RetryAttempts"; 12256bd5a8d2SGunnar Mills // If AutomaticRetry (AutoReboot) is enabled see how many 12266bd5a8d2SGunnar Mills // attempts are left 12276bd5a8d2SGunnar Mills crow::connections::systemBus->async_method_call( 1228cb13a392SEd Tanous [aResp](const boost::system::error_code ec2, 12296bd5a8d2SGunnar Mills std::variant<uint32_t>& autoRebootAttemptsLeft) { 1230cb13a392SEd Tanous if (ec2) 12316bd5a8d2SGunnar Mills { 1232cb13a392SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2; 12336bd5a8d2SGunnar Mills return; 12346bd5a8d2SGunnar Mills } 12356bd5a8d2SGunnar Mills 12366bd5a8d2SGunnar Mills const uint32_t* autoRebootAttemptsLeftPtr = 12376bd5a8d2SGunnar Mills std::get_if<uint32_t>(&autoRebootAttemptsLeft); 12386bd5a8d2SGunnar Mills 12396bd5a8d2SGunnar Mills if (!autoRebootAttemptsLeftPtr) 12406bd5a8d2SGunnar Mills { 12416bd5a8d2SGunnar Mills messages::internalError(aResp->res); 12426bd5a8d2SGunnar Mills return; 12436bd5a8d2SGunnar Mills } 12446bd5a8d2SGunnar Mills 12456bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: " 12466bd5a8d2SGunnar Mills << *autoRebootAttemptsLeftPtr; 12476bd5a8d2SGunnar Mills 12486bd5a8d2SGunnar Mills aResp->res 12496bd5a8d2SGunnar Mills .jsonValue["Boot"] 12506bd5a8d2SGunnar Mills ["RemainingAutomaticRetryAttempts"] = 12516bd5a8d2SGunnar Mills *autoRebootAttemptsLeftPtr; 12526bd5a8d2SGunnar Mills }, 12536bd5a8d2SGunnar Mills "xyz.openbmc_project.State.Host", 12546bd5a8d2SGunnar Mills "/xyz/openbmc_project/state/host0", 12556bd5a8d2SGunnar Mills "org.freedesktop.DBus.Properties", "Get", 12566bd5a8d2SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootAttempts", 12576bd5a8d2SGunnar Mills "AttemptsLeft"); 12586bd5a8d2SGunnar Mills } 12596bd5a8d2SGunnar Mills else 12606bd5a8d2SGunnar Mills { 12616bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12626bd5a8d2SGunnar Mills "Disabled"; 12636bd5a8d2SGunnar Mills } 12646bd5a8d2SGunnar Mills 12656bd5a8d2SGunnar Mills // Not on D-Bus. Hardcoded here: 12666bd5a8d2SGunnar Mills // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71 12676bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3; 126869f35306SGunnar Mills 126969f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 127069f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 127169f35306SGunnar Mills // RetryAttempts. 127269f35306SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish." 127369f35306SGunnar Mills "AllowableValues"] = {"Disabled", 127469f35306SGunnar Mills "RetryAttempts"}; 12756bd5a8d2SGunnar Mills }, 12766bd5a8d2SGunnar Mills "xyz.openbmc_project.Settings", 12776bd5a8d2SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 12786bd5a8d2SGunnar Mills "org.freedesktop.DBus.Properties", "Get", 12796bd5a8d2SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot"); 12806bd5a8d2SGunnar Mills } 12816bd5a8d2SGunnar Mills 12826bd5a8d2SGunnar Mills /** 1283c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1284c6a620f2SGeorge Liu * 1285c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1286c6a620f2SGeorge Liu * 1287c6a620f2SGeorge Liu * @return None. 1288c6a620f2SGeorge Liu */ 12898d1b46d7Szhanghch05 inline void 12908d1b46d7Szhanghch05 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1291c6a620f2SGeorge Liu { 1292c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1293c6a620f2SGeorge Liu 1294c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1295c6a620f2SGeorge Liu [aResp](const boost::system::error_code ec, 129619bd78d9SPatrick Williams std::variant<std::string>& policy) { 1297c6a620f2SGeorge Liu if (ec) 1298c6a620f2SGeorge Liu { 1299c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1300c6a620f2SGeorge Liu return; 1301c6a620f2SGeorge Liu } 1302c6a620f2SGeorge Liu 1303c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> 1304c6a620f2SGeorge Liu policyMaps = { 1305c6a620f2SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1306c6a620f2SGeorge Liu "AlwaysOn", 1307c6a620f2SGeorge Liu "AlwaysOn"}, 1308c6a620f2SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1309c6a620f2SGeorge Liu "AlwaysOff", 1310c6a620f2SGeorge Liu "AlwaysOff"}, 1311c6a620f2SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 131237ec9072SGunnar Mills "Restore", 1313c6a620f2SGeorge Liu "LastState"}}; 1314c6a620f2SGeorge Liu 1315c6a620f2SGeorge Liu const std::string* policyPtr = std::get_if<std::string>(&policy); 1316c6a620f2SGeorge Liu 1317c6a620f2SGeorge Liu if (!policyPtr) 1318c6a620f2SGeorge Liu { 1319c6a620f2SGeorge Liu messages::internalError(aResp->res); 1320c6a620f2SGeorge Liu return; 1321c6a620f2SGeorge Liu } 1322c6a620f2SGeorge Liu 1323c6a620f2SGeorge Liu auto policyMapsIt = policyMaps.find(*policyPtr); 1324c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1325c6a620f2SGeorge Liu { 1326c6a620f2SGeorge Liu messages::internalError(aResp->res); 1327c6a620f2SGeorge Liu return; 1328c6a620f2SGeorge Liu } 1329c6a620f2SGeorge Liu 1330c6a620f2SGeorge Liu aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second; 1331c6a620f2SGeorge Liu }, 1332c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1333c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1334c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Get", 1335c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", 1336c6a620f2SGeorge Liu "PowerRestorePolicy"); 1337c6a620f2SGeorge Liu } 1338c6a620f2SGeorge Liu 1339c6a620f2SGeorge Liu /** 13401981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13411981771bSAli Ahmed * TPM is required for booting the host. 13421981771bSAli Ahmed * 13431981771bSAli Ahmed * @param[in] aResp Shared pointer for generating response message. 13441981771bSAli Ahmed * 13451981771bSAli Ahmed * @return None. 13461981771bSAli Ahmed */ 13471981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 13481981771bSAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp) 13491981771bSAli Ahmed { 13501981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 13511981771bSAli Ahmed 13521981771bSAli Ahmed crow::connections::systemBus->async_method_call( 13531981771bSAli Ahmed [aResp]( 13541981771bSAli Ahmed const boost::system::error_code ec, 13551981771bSAli Ahmed std::vector<std::pair< 13561981771bSAli Ahmed std::string, 13571981771bSAli Ahmed std::vector<std::pair<std::string, std::vector<std::string>>>>>& 13581981771bSAli Ahmed subtree) { 13591981771bSAli Ahmed if (ec) 13601981771bSAli Ahmed { 13611981771bSAli Ahmed BMCWEB_LOG_DEBUG 13621981771bSAli Ahmed << "DBUS response error on TPM.Policy GetSubTree" << ec; 13631981771bSAli Ahmed // This is an optional D-Bus object so just return if 13641981771bSAli Ahmed // error occurs 13651981771bSAli Ahmed return; 13661981771bSAli Ahmed } 13671981771bSAli Ahmed if (subtree.size() == 0) 13681981771bSAli Ahmed { 13691981771bSAli Ahmed // As noted above, this is an optional interface so just return 13701981771bSAli Ahmed // if there is no instance found 13711981771bSAli Ahmed return; 13721981771bSAli Ahmed } 13731981771bSAli Ahmed 13741981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 13751981771bSAli Ahmed if (subtree.size() > 1) 13761981771bSAli Ahmed { 13771981771bSAli Ahmed BMCWEB_LOG_DEBUG 13781981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 13791981771bSAli Ahmed << subtree.size(); 13801981771bSAli Ahmed // Throw an internal Error and return 13811981771bSAli Ahmed messages::internalError(aResp->res); 13821981771bSAli Ahmed return; 13831981771bSAli Ahmed } 13841981771bSAli Ahmed 13851981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 13861981771bSAli Ahmed // field 13871981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 13881981771bSAli Ahmed { 13891981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 13901981771bSAli Ahmed messages::internalError(aResp->res); 13911981771bSAli Ahmed return; 13921981771bSAli Ahmed } 13931981771bSAli Ahmed 13941981771bSAli Ahmed const std::string& path = subtree[0].first; 13951981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 13961981771bSAli Ahmed 13971981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 13981981771bSAli Ahmed crow::connections::systemBus->async_method_call( 13991981771bSAli Ahmed [aResp](const boost::system::error_code ec, 14001981771bSAli Ahmed std::variant<bool>& tpmRequired) { 14011981771bSAli Ahmed if (ec) 14021981771bSAli Ahmed { 14031981771bSAli Ahmed BMCWEB_LOG_DEBUG 14041981771bSAli Ahmed << "D-BUS response error on TPM.Policy Get" << ec; 14051981771bSAli Ahmed messages::internalError(aResp->res); 14061981771bSAli Ahmed return; 14071981771bSAli Ahmed } 14081981771bSAli Ahmed 14091981771bSAli Ahmed const bool* tpmRequiredVal = 14101981771bSAli Ahmed std::get_if<bool>(&tpmRequired); 14111981771bSAli Ahmed 14121981771bSAli Ahmed if (!tpmRequiredVal) 14131981771bSAli Ahmed { 14141981771bSAli Ahmed messages::internalError(aResp->res); 14151981771bSAli Ahmed return; 14161981771bSAli Ahmed } 14171981771bSAli Ahmed 14181981771bSAli Ahmed if (*tpmRequiredVal == true) 14191981771bSAli Ahmed { 14201981771bSAli Ahmed aResp->res 14211981771bSAli Ahmed .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14221981771bSAli Ahmed "Required"; 14231981771bSAli Ahmed } 14241981771bSAli Ahmed else 14251981771bSAli Ahmed { 14261981771bSAli Ahmed aResp->res 14271981771bSAli Ahmed .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14281981771bSAli Ahmed "Disabled"; 14291981771bSAli Ahmed } 14301981771bSAli Ahmed }, 14311981771bSAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Get", 14321981771bSAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable"); 14331981771bSAli Ahmed }, 14341981771bSAli Ahmed "xyz.openbmc_project.ObjectMapper", 14351981771bSAli Ahmed "/xyz/openbmc_project/object_mapper", 14361981771bSAli Ahmed "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 14371981771bSAli Ahmed std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"}); 14381981771bSAli Ahmed } 14391981771bSAli Ahmed 14401981771bSAli Ahmed /** 14411c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14421c05dae3SAli Ahmed * TPM is required for booting the host. 14431c05dae3SAli Ahmed * 14441c05dae3SAli Ahmed * @param[in] aResp Shared pointer for generating response message. 14451c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14461c05dae3SAli Ahmed * 14471c05dae3SAli Ahmed * @return None. 14481c05dae3SAli Ahmed */ 14491c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 14501c05dae3SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired) 14511c05dae3SAli Ahmed { 14521c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 14531c05dae3SAli Ahmed 14541c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 14551c05dae3SAli Ahmed [aResp, tpmRequired]( 14561c05dae3SAli Ahmed const boost::system::error_code ec, 14571c05dae3SAli Ahmed std::vector<std::pair< 14581c05dae3SAli Ahmed std::string, 14591c05dae3SAli Ahmed std::vector<std::pair<std::string, std::vector<std::string>>>>>& 14601c05dae3SAli Ahmed subtree) { 14611c05dae3SAli Ahmed if (ec) 14621c05dae3SAli Ahmed { 14631c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 14641c05dae3SAli Ahmed << "DBUS response error on TPM.Policy GetSubTree" << ec; 14651c05dae3SAli Ahmed messages::internalError(aResp->res); 14661c05dae3SAli Ahmed return; 14671c05dae3SAli Ahmed } 14681c05dae3SAli Ahmed if (subtree.size() == 0) 14691c05dae3SAli Ahmed { 14701c05dae3SAli Ahmed messages::propertyValueNotInList(aResp->res, "ComputerSystem", 14711c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 14721c05dae3SAli Ahmed return; 14731c05dae3SAli Ahmed } 14741c05dae3SAli Ahmed 14751c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 14761c05dae3SAli Ahmed if (subtree.size() > 1) 14771c05dae3SAli Ahmed { 14781c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 14791c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 14801c05dae3SAli Ahmed << subtree.size(); 14811c05dae3SAli Ahmed // Throw an internal Error and return 14821c05dae3SAli Ahmed messages::internalError(aResp->res); 14831c05dae3SAli Ahmed return; 14841c05dae3SAli Ahmed } 14851c05dae3SAli Ahmed 14861c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 14871c05dae3SAli Ahmed // field 14881c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14891c05dae3SAli Ahmed { 14901c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 14911c05dae3SAli Ahmed messages::internalError(aResp->res); 14921c05dae3SAli Ahmed return; 14931c05dae3SAli Ahmed } 14941c05dae3SAli Ahmed 14951c05dae3SAli Ahmed const std::string& path = subtree[0].first; 14961c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14971c05dae3SAli Ahmed 14981c05dae3SAli Ahmed if (serv.empty()) 14991c05dae3SAli Ahmed { 15001c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 15011c05dae3SAli Ahmed messages::internalError(aResp->res); 15021c05dae3SAli Ahmed return; 15031c05dae3SAli Ahmed } 15041c05dae3SAli Ahmed 15051c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 15061c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 15071c05dae3SAli Ahmed [aResp](const boost::system::error_code ec) { 15081c05dae3SAli Ahmed if (ec) 15091c05dae3SAli Ahmed { 15101c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "DBUS response error: Set " 15111c05dae3SAli Ahmed "TrustedModuleRequiredToBoot" 15121c05dae3SAli Ahmed << ec; 15131c05dae3SAli Ahmed messages::internalError(aResp->res); 15141c05dae3SAli Ahmed return; 15151c05dae3SAli Ahmed } 15161c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 15171c05dae3SAli Ahmed }, 15181c05dae3SAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Set", 15191c05dae3SAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 15201c05dae3SAli Ahmed std::variant<bool>(tpmRequired)); 15211c05dae3SAli Ahmed }, 15221c05dae3SAli Ahmed "xyz.openbmc_project.ObjectMapper", 15231c05dae3SAli Ahmed "/xyz/openbmc_project/object_mapper", 15241c05dae3SAli Ahmed "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 15251c05dae3SAli Ahmed std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"}); 15261c05dae3SAli Ahmed } 15271c05dae3SAli Ahmed 15281c05dae3SAli Ahmed /** 1529491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1530491d8ee7SSantosh Puranik * 1531491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1532cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1533cd9a4666SKonstantin Aladyshev * @return Integer error code. 1534cd9a4666SKonstantin Aladyshev */ 1535cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1536cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1537cd9a4666SKonstantin Aladyshev { 1538c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1539cd9a4666SKonstantin Aladyshev 1540c21865c4SKonstantin Aladyshev if (!bootType) 1541cd9a4666SKonstantin Aladyshev { 1542c21865c4SKonstantin Aladyshev return; 1543c21865c4SKonstantin Aladyshev } 1544c21865c4SKonstantin Aladyshev 1545cd9a4666SKonstantin Aladyshev // Source target specified 1546cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1547cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1548cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1549cd9a4666SKonstantin Aladyshev { 1550cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1551cd9a4666SKonstantin Aladyshev } 1552cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1553cd9a4666SKonstantin Aladyshev { 1554cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1555cd9a4666SKonstantin Aladyshev } 1556cd9a4666SKonstantin Aladyshev else 1557cd9a4666SKonstantin Aladyshev { 1558cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1559cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1560cd9a4666SKonstantin Aladyshev << *bootType; 1561cd9a4666SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootType, 1562cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1563cd9a4666SKonstantin Aladyshev return; 1564cd9a4666SKonstantin Aladyshev } 1565cd9a4666SKonstantin Aladyshev 1566cd9a4666SKonstantin Aladyshev // Act on validated parameters 1567cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1568cd9a4666SKonstantin Aladyshev 1569cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1570c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1571cd9a4666SKonstantin Aladyshev if (ec) 1572cd9a4666SKonstantin Aladyshev { 1573cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1574cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1575cd9a4666SKonstantin Aladyshev { 1576cd9a4666SKonstantin Aladyshev messages::resourceNotFound(aResp->res, "Set", "BootType"); 1577cd9a4666SKonstantin Aladyshev return; 1578cd9a4666SKonstantin Aladyshev } 1579cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 1580cd9a4666SKonstantin Aladyshev return; 1581cd9a4666SKonstantin Aladyshev } 1582cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1583cd9a4666SKonstantin Aladyshev }, 1584c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1585c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1586cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1587cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1588cd9a4666SKonstantin Aladyshev std::variant<std::string>(bootTypeStr)); 1589cd9a4666SKonstantin Aladyshev } 1590cd9a4666SKonstantin Aladyshev 1591cd9a4666SKonstantin Aladyshev /** 1592cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1593cd9a4666SKonstantin Aladyshev * 1594cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1595c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1596c21865c4SKonstantin Aladyshev * @return Integer error code. 1597c21865c4SKonstantin Aladyshev */ 1598c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1599c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1600c21865c4SKonstantin Aladyshev { 1601c21865c4SKonstantin Aladyshev if (!bootEnable) 1602c21865c4SKonstantin Aladyshev { 1603c21865c4SKonstantin Aladyshev return; 1604c21865c4SKonstantin Aladyshev } 1605c21865c4SKonstantin Aladyshev // Source target specified 1606c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1607c21865c4SKonstantin Aladyshev 1608c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1609c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1610c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1611c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1612c21865c4SKonstantin Aladyshev { 1613c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1614c21865c4SKonstantin Aladyshev } 1615c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1616c21865c4SKonstantin Aladyshev { 1617c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1618c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1619c21865c4SKonstantin Aladyshev } 1620c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1621c21865c4SKonstantin Aladyshev { 1622c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1623c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1624c21865c4SKonstantin Aladyshev } 1625c21865c4SKonstantin Aladyshev else 1626c21865c4SKonstantin Aladyshev { 1627c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1628c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled: " 1629c21865c4SKonstantin Aladyshev << *bootEnable; 1630c21865c4SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootEnable, 1631c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1632c21865c4SKonstantin Aladyshev return; 1633c21865c4SKonstantin Aladyshev } 1634c21865c4SKonstantin Aladyshev 1635c21865c4SKonstantin Aladyshev // Act on validated parameters 1636c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1637c21865c4SKonstantin Aladyshev 1638c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1639c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1640c21865c4SKonstantin Aladyshev if (ec) 1641c21865c4SKonstantin Aladyshev { 1642c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1643c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1644c21865c4SKonstantin Aladyshev return; 1645c21865c4SKonstantin Aladyshev } 1646c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1647c21865c4SKonstantin Aladyshev }, 1648c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1649c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1650c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1651c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1652c21865c4SKonstantin Aladyshev std::variant<bool>(bootOverrideEnable)); 1653c21865c4SKonstantin Aladyshev 1654c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1655c21865c4SKonstantin Aladyshev { 1656c21865c4SKonstantin Aladyshev return; 1657c21865c4SKonstantin Aladyshev } 1658c21865c4SKonstantin Aladyshev 1659c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1660c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1661c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1662c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1663c21865c4SKonstantin Aladyshev 1664c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1665c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1666c21865c4SKonstantin Aladyshev if (ec) 1667c21865c4SKonstantin Aladyshev { 1668c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1669c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1670c21865c4SKonstantin Aladyshev return; 1671c21865c4SKonstantin Aladyshev } 1672c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1673c21865c4SKonstantin Aladyshev }, 1674c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1675c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1676c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1677c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1678c21865c4SKonstantin Aladyshev std::variant<bool>(!bootOverridePersistent)); 1679c21865c4SKonstantin Aladyshev } 1680c21865c4SKonstantin Aladyshev 1681c21865c4SKonstantin Aladyshev /** 1682c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1683c21865c4SKonstantin Aladyshev * 1684c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1685491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1686491d8ee7SSantosh Puranik * 1687265c1602SJohnathan Mantey * @return Integer error code. 1688491d8ee7SSantosh Puranik */ 1689cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1690cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1691491d8ee7SSantosh Puranik { 1692c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1693c21865c4SKonstantin Aladyshev std::string bootModeStr; 1694944ffaf9SJohnathan Mantey 1695c21865c4SKonstantin Aladyshev if (!bootSource) 1696491d8ee7SSantosh Puranik { 1697c21865c4SKonstantin Aladyshev return; 1698c21865c4SKonstantin Aladyshev } 1699c21865c4SKonstantin Aladyshev 1700491d8ee7SSantosh Puranik // Source target specified 1701491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1702491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1703c21865c4SKonstantin Aladyshev if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr)) 1704491d8ee7SSantosh Puranik { 1705944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1706944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1707491d8ee7SSantosh Puranik << *bootSource; 1708491d8ee7SSantosh Puranik messages::propertyValueNotInList(aResp->res, *bootSource, 1709491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1710491d8ee7SSantosh Puranik return; 1711491d8ee7SSantosh Puranik } 1712491d8ee7SSantosh Puranik 1713944ffaf9SJohnathan Mantey // Act on validated parameters 1714944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1715944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1716944ffaf9SJohnathan Mantey 1717491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1718491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1719491d8ee7SSantosh Puranik if (ec) 1720491d8ee7SSantosh Puranik { 1721491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1722491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1723491d8ee7SSantosh Puranik return; 1724491d8ee7SSantosh Puranik } 1725491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1726491d8ee7SSantosh Puranik }, 1727c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1728c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1729491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1730491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1731491d8ee7SSantosh Puranik std::variant<std::string>(bootSourceStr)); 1732944ffaf9SJohnathan Mantey 1733491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1734491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1735491d8ee7SSantosh Puranik if (ec) 1736491d8ee7SSantosh Puranik { 1737491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1738491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1739491d8ee7SSantosh Puranik return; 1740491d8ee7SSantosh Puranik } 1741491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1742491d8ee7SSantosh Puranik }, 1743c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1744c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1745491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1746491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1747491d8ee7SSantosh Puranik std::variant<std::string>(bootModeStr)); 1748cd9a4666SKonstantin Aladyshev } 1749944ffaf9SJohnathan Mantey 1750cd9a4666SKonstantin Aladyshev /** 1751c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1752491d8ee7SSantosh Puranik * 1753491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1754491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1755cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1756491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1757491d8ee7SSantosh Puranik * 1758265c1602SJohnathan Mantey * @return Integer error code. 1759491d8ee7SSantosh Puranik */ 1760c21865c4SKonstantin Aladyshev 1761c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1762c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1763c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1764c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1765491d8ee7SSantosh Puranik { 1766491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1767491d8ee7SSantosh Puranik 1768c21865c4SKonstantin Aladyshev setBootModeOrSource(aResp, bootSource); 1769c21865c4SKonstantin Aladyshev setBootType(aResp, bootType); 1770c21865c4SKonstantin Aladyshev setBootEnable(aResp, bootEnable); 1771491d8ee7SSantosh Puranik } 1772491d8ee7SSantosh Puranik 1773c6a620f2SGeorge Liu /** 177498e386ecSGunnar Mills * @brief Sets AssetTag 177598e386ecSGunnar Mills * 177698e386ecSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 177798e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 177898e386ecSGunnar Mills * 177998e386ecSGunnar Mills * @return None. 178098e386ecSGunnar Mills */ 17818d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 178298e386ecSGunnar Mills const std::string& assetTag) 178398e386ecSGunnar Mills { 178498e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 178598e386ecSGunnar Mills [aResp, assetTag]( 178698e386ecSGunnar Mills const boost::system::error_code ec, 178798e386ecSGunnar Mills const std::vector<std::pair< 178898e386ecSGunnar Mills std::string, 178998e386ecSGunnar Mills std::vector<std::pair<std::string, std::vector<std::string>>>>>& 179098e386ecSGunnar Mills subtree) { 179198e386ecSGunnar Mills if (ec) 179298e386ecSGunnar Mills { 179398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 179498e386ecSGunnar Mills messages::internalError(aResp->res); 179598e386ecSGunnar Mills return; 179698e386ecSGunnar Mills } 179798e386ecSGunnar Mills if (subtree.size() == 0) 179898e386ecSGunnar Mills { 179998e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 180098e386ecSGunnar Mills messages::internalError(aResp->res); 180198e386ecSGunnar Mills return; 180298e386ecSGunnar Mills } 180398e386ecSGunnar Mills // Assume only 1 system D-Bus object 180498e386ecSGunnar Mills // Throw an error if there is more than 1 180598e386ecSGunnar Mills if (subtree.size() > 1) 180698e386ecSGunnar Mills { 180798e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 180898e386ecSGunnar Mills messages::internalError(aResp->res); 180998e386ecSGunnar Mills return; 181098e386ecSGunnar Mills } 181198e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 181298e386ecSGunnar Mills { 181398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 181498e386ecSGunnar Mills messages::internalError(aResp->res); 181598e386ecSGunnar Mills return; 181698e386ecSGunnar Mills } 181798e386ecSGunnar Mills 181898e386ecSGunnar Mills const std::string& path = subtree[0].first; 181998e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 182098e386ecSGunnar Mills 182198e386ecSGunnar Mills if (service.empty()) 182298e386ecSGunnar Mills { 182398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 182498e386ecSGunnar Mills messages::internalError(aResp->res); 182598e386ecSGunnar Mills return; 182698e386ecSGunnar Mills } 182798e386ecSGunnar Mills 182898e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 182998e386ecSGunnar Mills [aResp](const boost::system::error_code ec2) { 183098e386ecSGunnar Mills if (ec2) 183198e386ecSGunnar Mills { 183298e386ecSGunnar Mills BMCWEB_LOG_DEBUG 183398e386ecSGunnar Mills << "D-Bus response error on AssetTag Set " << ec2; 183498e386ecSGunnar Mills messages::internalError(aResp->res); 183598e386ecSGunnar Mills return; 183698e386ecSGunnar Mills } 183798e386ecSGunnar Mills }, 183898e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 183998e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 184098e386ecSGunnar Mills std::variant<std::string>(assetTag)); 184198e386ecSGunnar Mills }, 184298e386ecSGunnar Mills "xyz.openbmc_project.ObjectMapper", 184398e386ecSGunnar Mills "/xyz/openbmc_project/object_mapper", 184498e386ecSGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 184598e386ecSGunnar Mills "/xyz/openbmc_project/inventory", int32_t(0), 184698e386ecSGunnar Mills std::array<const char*, 1>{ 184798e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Item.System"}); 184898e386ecSGunnar Mills } 184998e386ecSGunnar Mills 185098e386ecSGunnar Mills /** 185169f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 185269f35306SGunnar Mills * 185369f35306SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 185469f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 185569f35306SGunnar Mills * 185669f35306SGunnar Mills * @return None. 185769f35306SGunnar Mills */ 18588d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1859f23b7296SEd Tanous const std::string& automaticRetryConfig) 186069f35306SGunnar Mills { 186169f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 186269f35306SGunnar Mills 186369f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 186469f35306SGunnar Mills bool autoRebootEnabled; 186569f35306SGunnar Mills 186669f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 186769f35306SGunnar Mills { 186869f35306SGunnar Mills autoRebootEnabled = false; 186969f35306SGunnar Mills } 187069f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 187169f35306SGunnar Mills { 187269f35306SGunnar Mills autoRebootEnabled = true; 187369f35306SGunnar Mills } 187469f35306SGunnar Mills else 187569f35306SGunnar Mills { 187669f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property value for " 187769f35306SGunnar Mills "AutomaticRetryConfig: " 187869f35306SGunnar Mills << automaticRetryConfig; 187969f35306SGunnar Mills messages::propertyValueNotInList(aResp->res, automaticRetryConfig, 188069f35306SGunnar Mills "AutomaticRetryConfig"); 188169f35306SGunnar Mills return; 188269f35306SGunnar Mills } 188369f35306SGunnar Mills 188469f35306SGunnar Mills crow::connections::systemBus->async_method_call( 188569f35306SGunnar Mills [aResp](const boost::system::error_code ec) { 188669f35306SGunnar Mills if (ec) 188769f35306SGunnar Mills { 188869f35306SGunnar Mills messages::internalError(aResp->res); 188969f35306SGunnar Mills return; 189069f35306SGunnar Mills } 189169f35306SGunnar Mills }, 189269f35306SGunnar Mills "xyz.openbmc_project.Settings", 189369f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 189469f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 189569f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 189669f35306SGunnar Mills std::variant<bool>(autoRebootEnabled)); 189769f35306SGunnar Mills } 189869f35306SGunnar Mills 189969f35306SGunnar Mills /** 1900c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1901c6a620f2SGeorge Liu * 1902c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1903c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1904c6a620f2SGeorge Liu * 1905c6a620f2SGeorge Liu * @return None. 1906c6a620f2SGeorge Liu */ 19078d1b46d7Szhanghch05 inline void 19088d1b46d7Szhanghch05 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 19094e69c904SGunnar Mills const std::string& policy) 1910c6a620f2SGeorge Liu { 1911c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1912c6a620f2SGeorge Liu 1913c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 1914c6a620f2SGeorge Liu {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1915c6a620f2SGeorge Liu "AlwaysOn"}, 1916c6a620f2SGeorge Liu {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1917c6a620f2SGeorge Liu "AlwaysOff"}, 1918c6a620f2SGeorge Liu {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 191937ec9072SGunnar Mills "Restore"}}; 1920c6a620f2SGeorge Liu 1921c6a620f2SGeorge Liu std::string powerRestorPolicy; 1922c6a620f2SGeorge Liu 19234e69c904SGunnar Mills auto policyMapsIt = policyMaps.find(policy); 1924c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1925c6a620f2SGeorge Liu { 19264e69c904SGunnar Mills messages::propertyValueNotInList(aResp->res, policy, 19274e69c904SGunnar Mills "PowerRestorePolicy"); 1928c6a620f2SGeorge Liu return; 1929c6a620f2SGeorge Liu } 1930c6a620f2SGeorge Liu 1931c6a620f2SGeorge Liu powerRestorPolicy = policyMapsIt->second; 1932c6a620f2SGeorge Liu 1933c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1934c6a620f2SGeorge Liu [aResp](const boost::system::error_code ec) { 1935c6a620f2SGeorge Liu if (ec) 1936c6a620f2SGeorge Liu { 1937c6a620f2SGeorge Liu messages::internalError(aResp->res); 1938c6a620f2SGeorge Liu return; 1939c6a620f2SGeorge Liu } 1940c6a620f2SGeorge Liu }, 1941c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1942c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1943c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1944c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1945c6a620f2SGeorge Liu std::variant<std::string>(powerRestorPolicy)); 1946c6a620f2SGeorge Liu } 1947c6a620f2SGeorge Liu 1948a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 1949a6349918SAppaRao Puli /** 1950a6349918SAppaRao Puli * @brief Retrieves provisioning status 1951a6349918SAppaRao Puli * 1952a6349918SAppaRao Puli * @param[in] aResp Shared pointer for completing asynchronous calls. 1953a6349918SAppaRao Puli * 1954a6349918SAppaRao Puli * @return None. 1955a6349918SAppaRao Puli */ 19568d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp) 1957a6349918SAppaRao Puli { 1958a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 1959a6349918SAppaRao Puli crow::connections::systemBus->async_method_call( 1960a6349918SAppaRao Puli [aResp](const boost::system::error_code ec, 19611214b7e7SGunnar Mills const std::vector<std::pair<std::string, VariantType>>& 19621214b7e7SGunnar Mills propertiesList) { 1963b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1964b99fb1a9SAppaRao Puli aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 196550626f4fSJames Feist aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 196650626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 196750626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 196850626f4fSJames Feist 1969a6349918SAppaRao Puli if (ec) 1970a6349918SAppaRao Puli { 1971a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1972b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1973b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1974a6349918SAppaRao Puli return; 1975a6349918SAppaRao Puli } 1976a6349918SAppaRao Puli 1977a6349918SAppaRao Puli const bool* provState = nullptr; 1978a6349918SAppaRao Puli const bool* lockState = nullptr; 1979a6349918SAppaRao Puli for (const std::pair<std::string, VariantType>& property : 1980a6349918SAppaRao Puli propertiesList) 1981a6349918SAppaRao Puli { 1982a6349918SAppaRao Puli if (property.first == "UfmProvisioned") 1983a6349918SAppaRao Puli { 1984a6349918SAppaRao Puli provState = std::get_if<bool>(&property.second); 1985a6349918SAppaRao Puli } 1986a6349918SAppaRao Puli else if (property.first == "UfmLocked") 1987a6349918SAppaRao Puli { 1988a6349918SAppaRao Puli lockState = std::get_if<bool>(&property.second); 1989a6349918SAppaRao Puli } 1990a6349918SAppaRao Puli } 1991a6349918SAppaRao Puli 1992a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 1993a6349918SAppaRao Puli { 1994a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 1995a6349918SAppaRao Puli messages::internalError(aResp->res); 1996a6349918SAppaRao Puli return; 1997a6349918SAppaRao Puli } 1998a6349918SAppaRao Puli 1999a6349918SAppaRao Puli if (*provState == true) 2000a6349918SAppaRao Puli { 2001a6349918SAppaRao Puli if (*lockState == true) 2002a6349918SAppaRao Puli { 2003a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2004a6349918SAppaRao Puli } 2005a6349918SAppaRao Puli else 2006a6349918SAppaRao Puli { 2007a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2008a6349918SAppaRao Puli } 2009a6349918SAppaRao Puli } 2010a6349918SAppaRao Puli else 2011a6349918SAppaRao Puli { 2012a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2013a6349918SAppaRao Puli } 2014a6349918SAppaRao Puli }, 2015a6349918SAppaRao Puli "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr", 2016a6349918SAppaRao Puli "org.freedesktop.DBus.Properties", "GetAll", 2017a6349918SAppaRao Puli "xyz.openbmc_project.PFR.Attributes"); 2018a6349918SAppaRao Puli } 2019a6349918SAppaRao Puli #endif 2020a6349918SAppaRao Puli 2021491d8ee7SSantosh Puranik /** 20223a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 20233a2d0424SChris Cain * 20243a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20253a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 20263a2d0424SChris Cain * 20273a2d0424SChris Cain * @return None. 20283a2d0424SChris Cain */ 20293a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 20303a2d0424SChris Cain const std::string& modeValue) 20313a2d0424SChris Cain { 20323a2d0424SChris Cain std::string modeString; 20333a2d0424SChris Cain 20343a2d0424SChris Cain if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 20353a2d0424SChris Cain "PowerMode.Static") 20363a2d0424SChris Cain { 20373a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "Static"; 20383a2d0424SChris Cain } 20393a2d0424SChris Cain else if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 20403a2d0424SChris Cain "PowerMode.MaximumPerformance") 20413a2d0424SChris Cain { 20423a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 20433a2d0424SChris Cain } 20443a2d0424SChris Cain else if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 20453a2d0424SChris Cain "PowerMode.PowerSaving") 20463a2d0424SChris Cain { 20473a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "PowerSaving"; 20483a2d0424SChris Cain } 20493a2d0424SChris Cain else if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 20503a2d0424SChris Cain "PowerMode.OEM") 20513a2d0424SChris Cain { 20523a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "OEM"; 20533a2d0424SChris Cain } 20543a2d0424SChris Cain else 20553a2d0424SChris Cain { 20563a2d0424SChris Cain // Any other values would be invalid 20573a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 20583a2d0424SChris Cain messages::internalError(aResp->res); 20593a2d0424SChris Cain } 20603a2d0424SChris Cain } 20613a2d0424SChris Cain 20623a2d0424SChris Cain /** 20633a2d0424SChris Cain * @brief Retrieves system power mode 20643a2d0424SChris Cain * 20653a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20663a2d0424SChris Cain * 20673a2d0424SChris Cain * @return None. 20683a2d0424SChris Cain */ 20693a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 20703a2d0424SChris Cain { 20713a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 20723a2d0424SChris Cain 20733a2d0424SChris Cain // Get Power Mode object path: 20743a2d0424SChris Cain crow::connections::systemBus->async_method_call( 20753a2d0424SChris Cain [aResp]( 20763a2d0424SChris Cain const boost::system::error_code ec, 20773a2d0424SChris Cain const std::vector<std::pair< 20783a2d0424SChris Cain std::string, 20793a2d0424SChris Cain std::vector<std::pair<std::string, std::vector<std::string>>>>>& 20803a2d0424SChris Cain subtree) { 20813a2d0424SChris Cain if (ec) 20823a2d0424SChris Cain { 20833a2d0424SChris Cain BMCWEB_LOG_DEBUG 20843a2d0424SChris Cain << "DBUS response error on Power.Mode GetSubTree " << ec; 20853a2d0424SChris Cain // This is an optional D-Bus object so just return if 20863a2d0424SChris Cain // error occurs 20873a2d0424SChris Cain return; 20883a2d0424SChris Cain } 20893a2d0424SChris Cain if (subtree.empty()) 20903a2d0424SChris Cain { 20913a2d0424SChris Cain // As noted above, this is an optional interface so just return 20923a2d0424SChris Cain // if there is no instance found 20933a2d0424SChris Cain return; 20943a2d0424SChris Cain } 20953a2d0424SChris Cain if (subtree.size() > 1) 20963a2d0424SChris Cain { 20973a2d0424SChris Cain // More then one PowerMode object is not supported and is an 20983a2d0424SChris Cain // error 20993a2d0424SChris Cain BMCWEB_LOG_DEBUG 21003a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 21013a2d0424SChris Cain << subtree.size(); 21023a2d0424SChris Cain messages::internalError(aResp->res); 21033a2d0424SChris Cain return; 21043a2d0424SChris Cain } 21053a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21063a2d0424SChris Cain { 21073a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 21083a2d0424SChris Cain messages::internalError(aResp->res); 21093a2d0424SChris Cain return; 21103a2d0424SChris Cain } 21113a2d0424SChris Cain const std::string& path = subtree[0].first; 21123a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21133a2d0424SChris Cain if (service.empty()) 21143a2d0424SChris Cain { 21153a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 21163a2d0424SChris Cain messages::internalError(aResp->res); 21173a2d0424SChris Cain return; 21183a2d0424SChris Cain } 21193a2d0424SChris Cain // Valid Power Mode object found, now read the current value 21203a2d0424SChris Cain crow::connections::systemBus->async_method_call( 21213a2d0424SChris Cain [aResp](const boost::system::error_code ec, 21223a2d0424SChris Cain const std::variant<std::string>& pmode) { 21233a2d0424SChris Cain if (ec) 21243a2d0424SChris Cain { 21253a2d0424SChris Cain BMCWEB_LOG_DEBUG 21263a2d0424SChris Cain << "DBUS response error on PowerMode Get: " << ec; 21273a2d0424SChris Cain messages::internalError(aResp->res); 21283a2d0424SChris Cain return; 21293a2d0424SChris Cain } 21303a2d0424SChris Cain 21313a2d0424SChris Cain const std::string* s = std::get_if<std::string>(&pmode); 21323a2d0424SChris Cain if (s == nullptr) 21333a2d0424SChris Cain { 21343a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Unable to get PowerMode value"; 21353a2d0424SChris Cain messages::internalError(aResp->res); 21363a2d0424SChris Cain return; 21373a2d0424SChris Cain } 21383a2d0424SChris Cain 21393a2d0424SChris Cain aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = 21403a2d0424SChris Cain {"Static", "MaximumPerformance", "PowerSaving"}; 21413a2d0424SChris Cain 21423a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Current power mode: " << *s; 21433a2d0424SChris Cain translatePowerMode(aResp, *s); 21443a2d0424SChris Cain }, 21453a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Get", 21463a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode"); 21473a2d0424SChris Cain }, 21483a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", 21493a2d0424SChris Cain "/xyz/openbmc_project/object_mapper", 21503a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 21513a2d0424SChris Cain std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"}); 21523a2d0424SChris Cain } 21533a2d0424SChris Cain 21543a2d0424SChris Cain /** 21553a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21563a2d0424SChris Cain * name associated with that string 21573a2d0424SChris Cain * 21583a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21593a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 21603a2d0424SChris Cain * 21613a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 21623a2d0424SChris Cain */ 21633a2d0424SChris Cain inline std::string 21643a2d0424SChris Cain validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21653a2d0424SChris Cain const std::string& modeString) 21663a2d0424SChris Cain { 21673a2d0424SChris Cain std::string mode; 21683a2d0424SChris Cain 21693a2d0424SChris Cain if (modeString == "Static") 21703a2d0424SChris Cain { 21713a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 21723a2d0424SChris Cain } 21733a2d0424SChris Cain else if (modeString == "MaximumPerformance") 21743a2d0424SChris Cain { 21753a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode." 21763a2d0424SChris Cain "MaximumPerformance"; 21773a2d0424SChris Cain } 21783a2d0424SChris Cain else if (modeString == "PowerSaving") 21793a2d0424SChris Cain { 21803a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 21813a2d0424SChris Cain } 21823a2d0424SChris Cain else 21833a2d0424SChris Cain { 21843a2d0424SChris Cain messages::propertyValueNotInList(aResp->res, modeString, "PowerMode"); 21853a2d0424SChris Cain } 21863a2d0424SChris Cain return mode; 21873a2d0424SChris Cain } 21883a2d0424SChris Cain 21893a2d0424SChris Cain /** 21903a2d0424SChris Cain * @brief Sets system power mode. 21913a2d0424SChris Cain * 21923a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21933a2d0424SChris Cain * @param[in] pmode System power mode from request. 21943a2d0424SChris Cain * 21953a2d0424SChris Cain * @return None. 21963a2d0424SChris Cain */ 21973a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21983a2d0424SChris Cain const std::string& pmode) 21993a2d0424SChris Cain { 22003a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 22013a2d0424SChris Cain 22023a2d0424SChris Cain std::string powerMode = validatePowerMode(aResp, pmode); 22033a2d0424SChris Cain if (powerMode.empty()) 22043a2d0424SChris Cain { 22053a2d0424SChris Cain return; 22063a2d0424SChris Cain } 22073a2d0424SChris Cain 22083a2d0424SChris Cain // Get Power Mode object path: 22093a2d0424SChris Cain crow::connections::systemBus->async_method_call( 22103a2d0424SChris Cain [aResp, powerMode]( 22113a2d0424SChris Cain const boost::system::error_code ec, 22123a2d0424SChris Cain const std::vector<std::pair< 22133a2d0424SChris Cain std::string, 22143a2d0424SChris Cain std::vector<std::pair<std::string, std::vector<std::string>>>>>& 22153a2d0424SChris Cain subtree) { 22163a2d0424SChris Cain if (ec) 22173a2d0424SChris Cain { 22183a2d0424SChris Cain BMCWEB_LOG_DEBUG 22193a2d0424SChris Cain << "DBUS response error on Power.Mode GetSubTree " << ec; 22203a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 22213a2d0424SChris Cain messages::internalError(aResp->res); 22223a2d0424SChris Cain return; 22233a2d0424SChris Cain } 22243a2d0424SChris Cain if (subtree.empty()) 22253a2d0424SChris Cain { 22263a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 22273a2d0424SChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 22283a2d0424SChris Cain "PowerMode"); 22293a2d0424SChris Cain return; 22303a2d0424SChris Cain } 22313a2d0424SChris Cain if (subtree.size() > 1) 22323a2d0424SChris Cain { 22333a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22343a2d0424SChris Cain // error 22353a2d0424SChris Cain BMCWEB_LOG_DEBUG 22363a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 22373a2d0424SChris Cain << subtree.size(); 22383a2d0424SChris Cain messages::internalError(aResp->res); 22393a2d0424SChris Cain return; 22403a2d0424SChris Cain } 22413a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22423a2d0424SChris Cain { 22433a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 22443a2d0424SChris Cain messages::internalError(aResp->res); 22453a2d0424SChris Cain return; 22463a2d0424SChris Cain } 22473a2d0424SChris Cain const std::string& path = subtree[0].first; 22483a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22493a2d0424SChris Cain if (service.empty()) 22503a2d0424SChris Cain { 22513a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 22523a2d0424SChris Cain messages::internalError(aResp->res); 22533a2d0424SChris Cain return; 22543a2d0424SChris Cain } 22553a2d0424SChris Cain 22563a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 22573a2d0424SChris Cain << path; 22583a2d0424SChris Cain 22593a2d0424SChris Cain // Set the Power Mode property 22603a2d0424SChris Cain crow::connections::systemBus->async_method_call( 22613a2d0424SChris Cain [aResp](const boost::system::error_code ec) { 22623a2d0424SChris Cain if (ec) 22633a2d0424SChris Cain { 22643a2d0424SChris Cain messages::internalError(aResp->res); 22653a2d0424SChris Cain return; 22663a2d0424SChris Cain } 22673a2d0424SChris Cain }, 22683a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 22693a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 22703a2d0424SChris Cain std::variant<std::string>(powerMode)); 22713a2d0424SChris Cain }, 22723a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", 22733a2d0424SChris Cain "/xyz/openbmc_project/object_mapper", 22743a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 22753a2d0424SChris Cain std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"}); 22763a2d0424SChris Cain } 22773a2d0424SChris Cain 22783a2d0424SChris Cain /** 227951709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 228051709ffdSYong Li * 228151709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 228251709ffdSYong Li * 228351709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 228451709ffdSYong Li * translation cannot be done, returns an empty string. 228551709ffdSYong Li */ 228623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 228751709ffdSYong Li { 228851709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 228951709ffdSYong Li { 229051709ffdSYong Li return "None"; 229151709ffdSYong Li } 22923174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 229351709ffdSYong Li { 229451709ffdSYong Li return "ResetSystem"; 229551709ffdSYong Li } 22963174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 229751709ffdSYong Li { 229851709ffdSYong Li return "PowerDown"; 229951709ffdSYong Li } 23003174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 230151709ffdSYong Li { 230251709ffdSYong Li return "PowerCycle"; 230351709ffdSYong Li } 230451709ffdSYong Li 230551709ffdSYong Li return ""; 230651709ffdSYong Li } 230751709ffdSYong Li 230851709ffdSYong Li /** 2309c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2310c45f0082SYong Li * 2311c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2312c45f0082SYong Li * 2313c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2314c45f0082SYong Li *If translation cannot be done, returns an empty string. 2315c45f0082SYong Li */ 2316c45f0082SYong Li 231723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2318c45f0082SYong Li { 2319c45f0082SYong Li if (rfAction == "None") 2320c45f0082SYong Li { 2321c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2322c45f0082SYong Li } 23233174e4dfSEd Tanous if (rfAction == "PowerCycle") 2324c45f0082SYong Li { 2325c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2326c45f0082SYong Li } 23273174e4dfSEd Tanous if (rfAction == "PowerDown") 2328c45f0082SYong Li { 2329c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2330c45f0082SYong Li } 23313174e4dfSEd Tanous if (rfAction == "ResetSystem") 2332c45f0082SYong Li { 2333c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2334c45f0082SYong Li } 2335c45f0082SYong Li 2336c45f0082SYong Li return ""; 2337c45f0082SYong Li } 2338c45f0082SYong Li 2339c45f0082SYong Li /** 234051709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 234151709ffdSYong Li * 234251709ffdSYong Li * @param[in] aResp Shared pointer for completing asynchronous calls. 234351709ffdSYong Li * 234451709ffdSYong Li * @return None. 234551709ffdSYong Li */ 23468d1b46d7Szhanghch05 inline void 23478d1b46d7Szhanghch05 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 234851709ffdSYong Li { 234951709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 235051709ffdSYong Li crow::connections::systemBus->async_method_call( 235151709ffdSYong Li [aResp](const boost::system::error_code ec, 235251709ffdSYong Li PropertiesType& properties) { 235351709ffdSYong Li if (ec) 235451709ffdSYong Li { 235551709ffdSYong Li // watchdog service is stopped 235651709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 235751709ffdSYong Li return; 235851709ffdSYong Li } 235951709ffdSYong Li 236051709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 236151709ffdSYong Li 236251709ffdSYong Li nlohmann::json& hostWatchdogTimer = 236351709ffdSYong Li aResp->res.jsonValue["HostWatchdogTimer"]; 236451709ffdSYong Li 236551709ffdSYong Li // watchdog service is running/enabled 236651709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 236751709ffdSYong Li 236851709ffdSYong Li for (const auto& property : properties) 236951709ffdSYong Li { 237051709ffdSYong Li BMCWEB_LOG_DEBUG << "prop=" << property.first; 237151709ffdSYong Li if (property.first == "Enabled") 237251709ffdSYong Li { 237351709ffdSYong Li const bool* state = std::get_if<bool>(&property.second); 237451709ffdSYong Li 237551709ffdSYong Li if (!state) 237651709ffdSYong Li { 237751709ffdSYong Li messages::internalError(aResp->res); 2378601af5edSChicago Duan return; 237951709ffdSYong Li } 238051709ffdSYong Li 238151709ffdSYong Li hostWatchdogTimer["FunctionEnabled"] = *state; 238251709ffdSYong Li } 238351709ffdSYong Li else if (property.first == "ExpireAction") 238451709ffdSYong Li { 238551709ffdSYong Li const std::string* s = 238651709ffdSYong Li std::get_if<std::string>(&property.second); 238751709ffdSYong Li if (!s) 238851709ffdSYong Li { 238951709ffdSYong Li messages::internalError(aResp->res); 2390601af5edSChicago Duan return; 239151709ffdSYong Li } 239251709ffdSYong Li 239351709ffdSYong Li std::string action = dbusToRfWatchdogAction(*s); 239451709ffdSYong Li if (action.empty()) 239551709ffdSYong Li { 239651709ffdSYong Li messages::internalError(aResp->res); 2397601af5edSChicago Duan return; 239851709ffdSYong Li } 239951709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 240051709ffdSYong Li } 240151709ffdSYong Li } 240251709ffdSYong Li }, 240351709ffdSYong Li "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0", 240451709ffdSYong Li "org.freedesktop.DBus.Properties", "GetAll", 240551709ffdSYong Li "xyz.openbmc_project.State.Watchdog"); 240651709ffdSYong Li } 240751709ffdSYong Li 240851709ffdSYong Li /** 2409c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2410c45f0082SYong Li * 2411c45f0082SYong Li * @param[in] aResp Shared pointer for generating response message. 2412c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2413c45f0082SYong Li * RF request. 2414c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2415c45f0082SYong Li * 2416c45f0082SYong Li * @return None. 2417c45f0082SYong Li */ 24188d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 2419c45f0082SYong Li const std::optional<bool> wdtEnable, 2420c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2421c45f0082SYong Li { 2422c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2423c45f0082SYong Li 2424c45f0082SYong Li if (wdtTimeOutAction) 2425c45f0082SYong Li { 2426c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2427c45f0082SYong Li // check if TimeOut Action is Valid 2428c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2429c45f0082SYong Li { 2430c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2431c45f0082SYong Li << *wdtTimeOutAction; 2432c45f0082SYong Li messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction, 2433c45f0082SYong Li "TimeoutAction"); 2434c45f0082SYong Li return; 2435c45f0082SYong Li } 2436c45f0082SYong Li 2437c45f0082SYong Li crow::connections::systemBus->async_method_call( 2438c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2439c45f0082SYong Li if (ec) 2440c45f0082SYong Li { 2441c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2442c45f0082SYong Li messages::internalError(aResp->res); 2443c45f0082SYong Li return; 2444c45f0082SYong Li } 2445c45f0082SYong Li }, 2446c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2447c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2448c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2449c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2450c45f0082SYong Li std::variant<std::string>(wdtTimeOutActStr)); 2451c45f0082SYong Li } 2452c45f0082SYong Li 2453c45f0082SYong Li if (wdtEnable) 2454c45f0082SYong Li { 2455c45f0082SYong Li crow::connections::systemBus->async_method_call( 2456c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2457c45f0082SYong Li if (ec) 2458c45f0082SYong Li { 2459c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2460c45f0082SYong Li messages::internalError(aResp->res); 2461c45f0082SYong Li return; 2462c45f0082SYong Li } 2463c45f0082SYong Li }, 2464c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2465c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2466c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2467c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2468c45f0082SYong Li std::variant<bool>(*wdtEnable)); 2469c45f0082SYong Li } 2470c45f0082SYong Li } 2471c45f0082SYong Li 247237bbf98cSChris Cain using ipsPropertiesType = 247337bbf98cSChris Cain std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>; 247437bbf98cSChris Cain /** 247537bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 247637bbf98cSChris Cain * 247737bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 247837bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 247937bbf98cSChris Cain * 248037bbf98cSChris Cain * @return true if successful 248137bbf98cSChris Cain */ 2482*f6674220SEd Tanous inline bool parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 248337bbf98cSChris Cain ipsPropertiesType& properties) 248437bbf98cSChris Cain { 248537bbf98cSChris Cain for (const auto& property : properties) 248637bbf98cSChris Cain { 248737bbf98cSChris Cain if (property.first == "Enabled") 248837bbf98cSChris Cain { 248937bbf98cSChris Cain const bool* state = std::get_if<bool>(&property.second); 249037bbf98cSChris Cain if (!state) 249137bbf98cSChris Cain { 249237bbf98cSChris Cain return false; 249337bbf98cSChris Cain } 249437bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"][property.first] = *state; 249537bbf98cSChris Cain } 249637bbf98cSChris Cain else if (property.first == "EnterUtilizationPercent") 249737bbf98cSChris Cain { 249837bbf98cSChris Cain const uint8_t* util = std::get_if<uint8_t>(&property.second); 249937bbf98cSChris Cain if (!util) 250037bbf98cSChris Cain { 250137bbf98cSChris Cain return false; 250237bbf98cSChris Cain } 250337bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util; 250437bbf98cSChris Cain } 250537bbf98cSChris Cain else if (property.first == "EnterDwellTime") 250637bbf98cSChris Cain { 250737bbf98cSChris Cain // Convert Dbus time from milliseconds to seconds 250837bbf98cSChris Cain const uint64_t* timeMilliseconds = 250937bbf98cSChris Cain std::get_if<uint64_t>(&property.second); 251037bbf98cSChris Cain if (!timeMilliseconds) 251137bbf98cSChris Cain { 251237bbf98cSChris Cain return false; 251337bbf98cSChris Cain } 251437bbf98cSChris Cain const std::chrono::duration<uint64_t, std::milli> ms( 251537bbf98cSChris Cain *timeMilliseconds); 251637bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 251737bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 251837bbf98cSChris Cain .count(); 251937bbf98cSChris Cain } 252037bbf98cSChris Cain else if (property.first == "ExitUtilizationPercent") 252137bbf98cSChris Cain { 252237bbf98cSChris Cain const uint8_t* util = std::get_if<uint8_t>(&property.second); 252337bbf98cSChris Cain if (!util) 252437bbf98cSChris Cain { 252537bbf98cSChris Cain return false; 252637bbf98cSChris Cain } 252737bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util; 252837bbf98cSChris Cain } 252937bbf98cSChris Cain else if (property.first == "ExitDwellTime") 253037bbf98cSChris Cain { 253137bbf98cSChris Cain // Convert Dbus time from milliseconds to seconds 253237bbf98cSChris Cain const uint64_t* timeMilliseconds = 253337bbf98cSChris Cain std::get_if<uint64_t>(&property.second); 253437bbf98cSChris Cain if (!timeMilliseconds) 253537bbf98cSChris Cain { 253637bbf98cSChris Cain return false; 253737bbf98cSChris Cain } 253837bbf98cSChris Cain const std::chrono::duration<uint64_t, std::milli> ms( 253937bbf98cSChris Cain *timeMilliseconds); 254037bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 254137bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 254237bbf98cSChris Cain .count(); 254337bbf98cSChris Cain } 254437bbf98cSChris Cain else 254537bbf98cSChris Cain { 254637bbf98cSChris Cain BMCWEB_LOG_WARNING << "Unexpected IdlePowerSaver property: " 254737bbf98cSChris Cain << property.first; 254837bbf98cSChris Cain } 254937bbf98cSChris Cain } 255037bbf98cSChris Cain 255137bbf98cSChris Cain return true; 255237bbf98cSChris Cain } 255337bbf98cSChris Cain 255437bbf98cSChris Cain /** 255537bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 255637bbf98cSChris Cain * 255737bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 255837bbf98cSChris Cain * 255937bbf98cSChris Cain * @return None. 256037bbf98cSChris Cain */ 256137bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 256237bbf98cSChris Cain { 256337bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 256437bbf98cSChris Cain 256537bbf98cSChris Cain // Get IdlePowerSaver object path: 256637bbf98cSChris Cain crow::connections::systemBus->async_method_call( 256737bbf98cSChris Cain [aResp]( 256837bbf98cSChris Cain const boost::system::error_code ec, 256937bbf98cSChris Cain const std::vector<std::pair< 257037bbf98cSChris Cain std::string, 257137bbf98cSChris Cain std::vector<std::pair<std::string, std::vector<std::string>>>>>& 257237bbf98cSChris Cain subtree) { 257337bbf98cSChris Cain if (ec) 257437bbf98cSChris Cain { 257537bbf98cSChris Cain BMCWEB_LOG_DEBUG 257637bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 257737bbf98cSChris Cain << ec; 257837bbf98cSChris Cain messages::internalError(aResp->res); 257937bbf98cSChris Cain return; 258037bbf98cSChris Cain } 258137bbf98cSChris Cain if (subtree.empty()) 258237bbf98cSChris Cain { 258337bbf98cSChris Cain // This is an optional interface so just return 258437bbf98cSChris Cain // if there is no instance found 258537bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 258637bbf98cSChris Cain return; 258737bbf98cSChris Cain } 258837bbf98cSChris Cain if (subtree.size() > 1) 258937bbf98cSChris Cain { 259037bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 259137bbf98cSChris Cain // is an error 259237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 259337bbf98cSChris Cain "Power.IdlePowerSaver objects: " 259437bbf98cSChris Cain << subtree.size(); 259537bbf98cSChris Cain messages::internalError(aResp->res); 259637bbf98cSChris Cain return; 259737bbf98cSChris Cain } 259837bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 259937bbf98cSChris Cain { 260037bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 260137bbf98cSChris Cain messages::internalError(aResp->res); 260237bbf98cSChris Cain return; 260337bbf98cSChris Cain } 260437bbf98cSChris Cain const std::string& path = subtree[0].first; 260537bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 260637bbf98cSChris Cain if (service.empty()) 260737bbf98cSChris Cain { 260837bbf98cSChris Cain BMCWEB_LOG_DEBUG 260937bbf98cSChris Cain << "Power.IdlePowerSaver service mapper error!"; 261037bbf98cSChris Cain messages::internalError(aResp->res); 261137bbf98cSChris Cain return; 261237bbf98cSChris Cain } 261337bbf98cSChris Cain 261437bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 261537bbf98cSChris Cain crow::connections::systemBus->async_method_call( 261637bbf98cSChris Cain [aResp](const boost::system::error_code ec, 261737bbf98cSChris Cain ipsPropertiesType& properties) { 261837bbf98cSChris Cain if (ec) 261937bbf98cSChris Cain { 262037bbf98cSChris Cain BMCWEB_LOG_ERROR 262137bbf98cSChris Cain << "DBUS response error on IdlePowerSaver GetAll: " 262237bbf98cSChris Cain << ec; 262337bbf98cSChris Cain messages::internalError(aResp->res); 262437bbf98cSChris Cain return; 262537bbf98cSChris Cain } 262637bbf98cSChris Cain 262737bbf98cSChris Cain if (parseIpsProperties(aResp, properties) == false) 262837bbf98cSChris Cain { 262937bbf98cSChris Cain messages::internalError(aResp->res); 263037bbf98cSChris Cain return; 263137bbf98cSChris Cain } 263237bbf98cSChris Cain }, 263337bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "GetAll", 263437bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver"); 263537bbf98cSChris Cain }, 263637bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", 263737bbf98cSChris Cain "/xyz/openbmc_project/object_mapper", 263837bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 263937bbf98cSChris Cain std::array<const char*, 1>{ 264037bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver"}); 264137bbf98cSChris Cain 264237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 264337bbf98cSChris Cain } 264437bbf98cSChris Cain 264537bbf98cSChris Cain /** 264637bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 264737bbf98cSChris Cain * 264837bbf98cSChris Cain * @param[in] aResp Shared pointer for generating response message. 264937bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 265037bbf98cSChris Cain * RF request. 265137bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 265237bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 265337bbf98cSChris Cain * before entering idle state. 265437bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 265537bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 265637bbf98cSChris Cain * before exiting idle state 265737bbf98cSChris Cain * 265837bbf98cSChris Cain * @return None. 265937bbf98cSChris Cain */ 266037bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 266137bbf98cSChris Cain const std::optional<bool> ipsEnable, 266237bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 266337bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 266437bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 266537bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 266637bbf98cSChris Cain { 266737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 266837bbf98cSChris Cain 266937bbf98cSChris Cain // Get IdlePowerSaver object path: 267037bbf98cSChris Cain crow::connections::systemBus->async_method_call( 267137bbf98cSChris Cain [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 267237bbf98cSChris Cain ipsExitTime]( 267337bbf98cSChris Cain const boost::system::error_code ec, 267437bbf98cSChris Cain const std::vector<std::pair< 267537bbf98cSChris Cain std::string, 267637bbf98cSChris Cain std::vector<std::pair<std::string, std::vector<std::string>>>>>& 267737bbf98cSChris Cain subtree) { 267837bbf98cSChris Cain if (ec) 267937bbf98cSChris Cain { 268037bbf98cSChris Cain BMCWEB_LOG_DEBUG 268137bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 268237bbf98cSChris Cain << ec; 268337bbf98cSChris Cain messages::internalError(aResp->res); 268437bbf98cSChris Cain return; 268537bbf98cSChris Cain } 268637bbf98cSChris Cain if (subtree.empty()) 268737bbf98cSChris Cain { 268837bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 268937bbf98cSChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 269037bbf98cSChris Cain "IdlePowerSaver"); 269137bbf98cSChris Cain return; 269237bbf98cSChris Cain } 269337bbf98cSChris Cain if (subtree.size() > 1) 269437bbf98cSChris Cain { 269537bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 269637bbf98cSChris Cain // is an error 269737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 269837bbf98cSChris Cain "Power.IdlePowerSaver objects: " 269937bbf98cSChris Cain << subtree.size(); 270037bbf98cSChris Cain messages::internalError(aResp->res); 270137bbf98cSChris Cain return; 270237bbf98cSChris Cain } 270337bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 270437bbf98cSChris Cain { 270537bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 270637bbf98cSChris Cain messages::internalError(aResp->res); 270737bbf98cSChris Cain return; 270837bbf98cSChris Cain } 270937bbf98cSChris Cain const std::string& path = subtree[0].first; 271037bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 271137bbf98cSChris Cain if (service.empty()) 271237bbf98cSChris Cain { 271337bbf98cSChris Cain BMCWEB_LOG_DEBUG 271437bbf98cSChris Cain << "Power.IdlePowerSaver service mapper error!"; 271537bbf98cSChris Cain messages::internalError(aResp->res); 271637bbf98cSChris Cain return; 271737bbf98cSChris Cain } 271837bbf98cSChris Cain 271937bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 272037bbf98cSChris Cain // need to be updated 272137bbf98cSChris Cain 272237bbf98cSChris Cain if (ipsEnable) 272337bbf98cSChris Cain { 272437bbf98cSChris Cain crow::connections::systemBus->async_method_call( 272537bbf98cSChris Cain [aResp](const boost::system::error_code ec) { 272637bbf98cSChris Cain if (ec) 272737bbf98cSChris Cain { 272837bbf98cSChris Cain BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 272937bbf98cSChris Cain messages::internalError(aResp->res); 273037bbf98cSChris Cain return; 273137bbf98cSChris Cain } 273237bbf98cSChris Cain }, 273337bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 273437bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 273537bbf98cSChris Cain "Enabled", std::variant<bool>(*ipsEnable)); 273637bbf98cSChris Cain } 273737bbf98cSChris Cain if (ipsEnterUtil) 273837bbf98cSChris Cain { 273937bbf98cSChris Cain crow::connections::systemBus->async_method_call( 274037bbf98cSChris Cain [aResp](const boost::system::error_code ec) { 274137bbf98cSChris Cain if (ec) 274237bbf98cSChris Cain { 274337bbf98cSChris Cain BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 274437bbf98cSChris Cain messages::internalError(aResp->res); 274537bbf98cSChris Cain return; 274637bbf98cSChris Cain } 274737bbf98cSChris Cain }, 274837bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 274937bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 275037bbf98cSChris Cain "EnterUtilizationPercent", 275137bbf98cSChris Cain std::variant<uint8_t>(*ipsEnterUtil)); 275237bbf98cSChris Cain } 275337bbf98cSChris Cain if (ipsEnterTime) 275437bbf98cSChris Cain { 275537bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 275637bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 275737bbf98cSChris Cain crow::connections::systemBus->async_method_call( 275837bbf98cSChris Cain [aResp](const boost::system::error_code ec) { 275937bbf98cSChris Cain if (ec) 276037bbf98cSChris Cain { 276137bbf98cSChris Cain BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 276237bbf98cSChris Cain messages::internalError(aResp->res); 276337bbf98cSChris Cain return; 276437bbf98cSChris Cain } 276537bbf98cSChris Cain }, 276637bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 276737bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 276837bbf98cSChris Cain "EnterDwellTime", std::variant<uint64_t>(timeMilliseconds)); 276937bbf98cSChris Cain } 277037bbf98cSChris Cain if (ipsExitUtil) 277137bbf98cSChris Cain { 277237bbf98cSChris Cain crow::connections::systemBus->async_method_call( 277337bbf98cSChris Cain [aResp](const boost::system::error_code ec) { 277437bbf98cSChris Cain if (ec) 277537bbf98cSChris Cain { 277637bbf98cSChris Cain BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 277737bbf98cSChris Cain messages::internalError(aResp->res); 277837bbf98cSChris Cain return; 277937bbf98cSChris Cain } 278037bbf98cSChris Cain }, 278137bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 278237bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 278337bbf98cSChris Cain "ExitUtilizationPercent", 278437bbf98cSChris Cain std::variant<uint8_t>(*ipsExitUtil)); 278537bbf98cSChris Cain } 278637bbf98cSChris Cain if (ipsExitTime) 278737bbf98cSChris Cain { 278837bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 278937bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 279037bbf98cSChris Cain crow::connections::systemBus->async_method_call( 279137bbf98cSChris Cain [aResp](const boost::system::error_code ec) { 279237bbf98cSChris Cain if (ec) 279337bbf98cSChris Cain { 279437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 279537bbf98cSChris Cain messages::internalError(aResp->res); 279637bbf98cSChris Cain return; 279737bbf98cSChris Cain } 279837bbf98cSChris Cain }, 279937bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 280037bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 280137bbf98cSChris Cain "ExitDwellTime", std::variant<uint64_t>(timeMilliseconds)); 280237bbf98cSChris Cain } 280337bbf98cSChris Cain }, 280437bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", 280537bbf98cSChris Cain "/xyz/openbmc_project/object_mapper", 280637bbf98cSChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 280737bbf98cSChris Cain std::array<const char*, 1>{ 280837bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver"}); 280937bbf98cSChris Cain 281037bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 281137bbf98cSChris Cain } 281237bbf98cSChris Cain 2813c45f0082SYong Li /** 2814c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 2815c5b2abe0SLewanczyk, Dawid * Schema 2816c5b2abe0SLewanczyk, Dawid */ 28177e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app) 28181abe55efSEd Tanous { 28197e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2820ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 28217e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 28224f48d5f6SEd Tanous [](const crow::Request& /*req*/, 28237e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 28248d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28250f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28268d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28278d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2828462023adSSunitha Harish 2829462023adSSunitha Harish crow::connections::systemBus->async_method_call( 28304f48d5f6SEd Tanous [asyncResp](const boost::system::error_code ec, 2831cb13a392SEd Tanous const std::variant<std::string>& /*hostName*/) { 28322c70f800SEd Tanous nlohmann::json& ifaceArray = 2833462023adSSunitha Harish asyncResp->res.jsonValue["Members"]; 28342c70f800SEd Tanous ifaceArray = nlohmann::json::array(); 28357e860f15SJohn Edward Broadbent auto& count = 28367e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Members@odata.count"]; 28372c70f800SEd Tanous ifaceArray.push_back( 2838cb13a392SEd Tanous {{"@odata.id", "/redfish/v1/Systems/system"}}); 283994bda602STim Lee count = ifaceArray.size(); 2840cb13a392SEd Tanous if (!ec) 2841462023adSSunitha Harish { 2842462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 28432c70f800SEd Tanous ifaceArray.push_back( 28447e860f15SJohn Edward Broadbent {{"@odata.id", 28457e860f15SJohn Edward Broadbent "/redfish/v1/Systems/hypervisor"}}); 28462c70f800SEd Tanous count = ifaceArray.size(); 2847cb13a392SEd Tanous } 2848462023adSSunitha Harish }, 28498e651fbfSSunitha Harish "xyz.openbmc_project.Settings", 28508e651fbfSSunitha Harish "/xyz/openbmc_project/network/hypervisor", 2851462023adSSunitha Harish "org.freedesktop.DBus.Properties", "Get", 28527e860f15SJohn Edward Broadbent "xyz.openbmc_project.Network.SystemConfiguration", 28537e860f15SJohn Edward Broadbent "HostName"); 28547e860f15SJohn Edward Broadbent }); 2855c5b2abe0SLewanczyk, Dawid } 28567e860f15SJohn Edward Broadbent 28577e860f15SJohn Edward Broadbent /** 28587e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28597e860f15SJohn Edward Broadbent */ 28604f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28617e860f15SJohn Edward Broadbent { 28627e860f15SJohn Edward Broadbent constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 28637e860f15SJohn Edward Broadbent constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 28647e860f15SJohn Edward Broadbent constexpr char const* interfaceName = 28657e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 28667e860f15SJohn Edward Broadbent constexpr char const* method = "NMI"; 28677e860f15SJohn Edward Broadbent 28687e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28697e860f15SJohn Edward Broadbent [asyncResp](const boost::system::error_code ec) { 28707e860f15SJohn Edward Broadbent if (ec) 28717e860f15SJohn Edward Broadbent { 28727e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 28737e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28747e860f15SJohn Edward Broadbent return; 28757e860f15SJohn Edward Broadbent } 28767e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28777e860f15SJohn Edward Broadbent }, 28787e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28797e860f15SJohn Edward Broadbent } 2880c5b2abe0SLewanczyk, Dawid 2881c5b2abe0SLewanczyk, Dawid /** 2882cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 2883cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 2884cc340dd9SEd Tanous */ 28857e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app) 2886cc340dd9SEd Tanous { 2887cc340dd9SEd Tanous /** 2888cc340dd9SEd Tanous * Function handles POST method request. 2889cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 2890cc340dd9SEd Tanous */ 28917e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 28927e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/") 2893ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 28947e860f15SJohn Edward Broadbent .methods( 28957e860f15SJohn Edward Broadbent boost::beast::http::verb:: 28967e860f15SJohn Edward Broadbent post)([](const crow::Request& req, 28977e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 28989712f8acSEd Tanous std::string resetType; 28997e860f15SJohn Edward Broadbent if (!json_util::readJson(req, asyncResp->res, "ResetType", 29007e860f15SJohn Edward Broadbent resetType)) 2901cc340dd9SEd Tanous { 2902cc340dd9SEd Tanous return; 2903cc340dd9SEd Tanous } 2904cc340dd9SEd Tanous 2905d22c8396SJason M. Bills // Get the command and host vs. chassis 2906cc340dd9SEd Tanous std::string command; 2907d22c8396SJason M. Bills bool hostCommand; 2908d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2909cc340dd9SEd Tanous { 2910cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2911d22c8396SJason M. Bills hostCommand = true; 2912d22c8396SJason M. Bills } 2913d22c8396SJason M. Bills else if (resetType == "ForceOff") 2914d22c8396SJason M. Bills { 2915d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2916d22c8396SJason M. Bills hostCommand = false; 2917d22c8396SJason M. Bills } 2918d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2919d22c8396SJason M. Bills { 292086a0851aSJason M. Bills command = 292186a0851aSJason M. Bills "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 292286a0851aSJason M. Bills hostCommand = true; 2923cc340dd9SEd Tanous } 29249712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2925cc340dd9SEd Tanous { 2926cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2927d22c8396SJason M. Bills hostCommand = true; 2928cc340dd9SEd Tanous } 29299712f8acSEd Tanous else if (resetType == "GracefulRestart") 2930cc340dd9SEd Tanous { 29317e860f15SJohn Edward Broadbent command = "xyz.openbmc_project.State.Host.Transition." 29327e860f15SJohn Edward Broadbent "GracefulWarmReboot"; 2933d22c8396SJason M. Bills hostCommand = true; 2934d22c8396SJason M. Bills } 2935d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2936d22c8396SJason M. Bills { 293786a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 293886a0851aSJason M. Bills hostCommand = true; 2939cc340dd9SEd Tanous } 2940bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2941bfd5b826SLakshminarayana R. Kammath { 2942bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2943bfd5b826SLakshminarayana R. Kammath return; 2944bfd5b826SLakshminarayana R. Kammath } 2945cc340dd9SEd Tanous else 2946cc340dd9SEd Tanous { 29478d1b46d7Szhanghch05 messages::actionParameterUnknown(asyncResp->res, "Reset", 29488d1b46d7Szhanghch05 resetType); 2949cc340dd9SEd Tanous return; 2950cc340dd9SEd Tanous } 2951cc340dd9SEd Tanous 2952d22c8396SJason M. Bills if (hostCommand) 2953d22c8396SJason M. Bills { 2954cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 2955d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2956cc340dd9SEd Tanous if (ec) 2957cc340dd9SEd Tanous { 2958cc340dd9SEd Tanous BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 29597e860f15SJohn Edward Broadbent if (ec.value() == 29607e860f15SJohn Edward Broadbent boost::asio::error::invalid_argument) 2961d22c8396SJason M. Bills { 2962d22c8396SJason M. Bills messages::actionParameterNotSupported( 2963d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2964d22c8396SJason M. Bills } 2965d22c8396SJason M. Bills else 2966d22c8396SJason M. Bills { 2967f12894f8SJason M. Bills messages::internalError(asyncResp->res); 2968d22c8396SJason M. Bills } 2969cc340dd9SEd Tanous return; 2970cc340dd9SEd Tanous } 2971f12894f8SJason M. Bills messages::success(asyncResp->res); 2972cc340dd9SEd Tanous }, 2973cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 2974cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 2975cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 29769712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 2977abf2add6SEd Tanous std::variant<std::string>{command}); 2978cc340dd9SEd Tanous } 2979d22c8396SJason M. Bills else 2980d22c8396SJason M. Bills { 2981d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 2982d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2983d22c8396SJason M. Bills if (ec) 2984d22c8396SJason M. Bills { 2985d22c8396SJason M. Bills BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 29867e860f15SJohn Edward Broadbent if (ec.value() == 29877e860f15SJohn Edward Broadbent boost::asio::error::invalid_argument) 2988d22c8396SJason M. Bills { 2989d22c8396SJason M. Bills messages::actionParameterNotSupported( 2990d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2991d22c8396SJason M. Bills } 2992d22c8396SJason M. Bills else 2993d22c8396SJason M. Bills { 2994d22c8396SJason M. Bills messages::internalError(asyncResp->res); 2995d22c8396SJason M. Bills } 2996d22c8396SJason M. Bills return; 2997d22c8396SJason M. Bills } 2998d22c8396SJason M. Bills messages::success(asyncResp->res); 2999d22c8396SJason M. Bills }, 3000d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 3001d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 3002d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 30037e860f15SJohn Edward Broadbent "xyz.openbmc_project.State.Chassis", 30047e860f15SJohn Edward Broadbent "RequestedPowerTransition", 3005d22c8396SJason M. Bills std::variant<std::string>{command}); 3006d22c8396SJason M. Bills } 30077e860f15SJohn Edward Broadbent }); 3008d22c8396SJason M. Bills } 3009cc340dd9SEd Tanous 3010cc340dd9SEd Tanous /** 30116617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 3012c5b2abe0SLewanczyk, Dawid */ 30137e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app) 30141abe55efSEd Tanous { 3015c5b2abe0SLewanczyk, Dawid 3016c5b2abe0SLewanczyk, Dawid /** 3017c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 3018c5b2abe0SLewanczyk, Dawid */ 30197e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 3020ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystem) 30217e860f15SJohn Edward Broadbent .methods( 30227e860f15SJohn Edward Broadbent boost::beast::http::verb:: 30237e860f15SJohn Edward Broadbent get)([](const crow::Request&, 30247e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 30258d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 302637bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 30278d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 30288d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 30298d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 30308d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 30318d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 30328d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 30338d1b46d7Szhanghch05 "Disabled"; 30348d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 30358d1b46d7Szhanghch05 uint64_t(0); 30368d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 30378d1b46d7Szhanghch05 "Disabled"; 30387e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.id"] = 30397e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system"; 304004a258f4SEd Tanous 30418d1b46d7Szhanghch05 asyncResp->res.jsonValue["Processors"] = { 3042029573d4SEd Tanous {"@odata.id", "/redfish/v1/Systems/system/Processors"}}; 30438d1b46d7Szhanghch05 asyncResp->res.jsonValue["Memory"] = { 3044029573d4SEd Tanous {"@odata.id", "/redfish/v1/Systems/system/Memory"}}; 30458d1b46d7Szhanghch05 asyncResp->res.jsonValue["Storage"] = { 3046a25aeccfSNikhil Potade {"@odata.id", "/redfish/v1/Systems/system/Storage"}}; 3047029573d4SEd Tanous 30488d1b46d7Szhanghch05 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = { 3049cc340dd9SEd Tanous {"target", 3050029573d4SEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"}, 30511cb1a9e6SAppaRao Puli {"@Redfish.ActionInfo", 30521cb1a9e6SAppaRao Puli "/redfish/v1/Systems/system/ResetActionInfo"}}; 3053c5b2abe0SLewanczyk, Dawid 30548d1b46d7Szhanghch05 asyncResp->res.jsonValue["LogServices"] = { 3055029573d4SEd Tanous {"@odata.id", "/redfish/v1/Systems/system/LogServices"}}; 3056c4bf6374SJason M. Bills 30578d1b46d7Szhanghch05 asyncResp->res.jsonValue["Bios"] = { 3058d82a3acdSCarol Wang {"@odata.id", "/redfish/v1/Systems/system/Bios"}}; 3059d82a3acdSCarol Wang 30608d1b46d7Szhanghch05 asyncResp->res.jsonValue["Links"]["ManagedBy"] = { 3061c5d03ff4SJennifer Lee {{"@odata.id", "/redfish/v1/Managers/bmc"}}}; 3062c5d03ff4SJennifer Lee 30638d1b46d7Szhanghch05 asyncResp->res.jsonValue["Status"] = { 3064c5d03ff4SJennifer Lee {"Health", "OK"}, 3065c5d03ff4SJennifer Lee {"State", "Enabled"}, 3066c5d03ff4SJennifer Lee }; 30670e8ac5e7SGunnar Mills 30680e8ac5e7SGunnar Mills // Fill in SerialConsole info 30690e8ac5e7SGunnar Mills asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 30700e8ac5e7SGunnar Mills 15; 30710e8ac5e7SGunnar Mills asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = { 30720e8ac5e7SGunnar Mills {"ServiceEnabled", true}, 30730e8ac5e7SGunnar Mills }; 30740e8ac5e7SGunnar Mills // TODO (Gunnar): Should look for obmc-console-ssh@2200.service 30750e8ac5e7SGunnar Mills asyncResp->res.jsonValue["SerialConsole"]["SSH"] = { 30760e8ac5e7SGunnar Mills {"ServiceEnabled", true}, 30770e8ac5e7SGunnar Mills {"Port", 2200}, 30780e8ac5e7SGunnar Mills // https://github.com/openbmc/docs/blob/master/console.md 30790e8ac5e7SGunnar Mills {"HotKeySequenceDisplay", "Press ~. to exit console"}, 30800e8ac5e7SGunnar Mills }; 30810e8ac5e7SGunnar Mills 30820e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 30830e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 30840e8ac5e7SGunnar Mills asyncResp->res.jsonValue["GraphicalConsole"] = { 30850e8ac5e7SGunnar Mills {"ServiceEnabled", true}, 30860e8ac5e7SGunnar Mills {"MaxConcurrentSessions", 4}, 30870e8ac5e7SGunnar Mills {"ConnectTypesSupported", {"KVMIP"}}, 30880e8ac5e7SGunnar Mills }; 30890e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 3090e284a7c1SJames Feist constexpr const std::array<const char*, 4> inventoryForSystems = { 3091b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 30922ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3093e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3094e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3095b49ac873SJames Feist 3096b49ac873SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 3097b49ac873SJames Feist crow::connections::systemBus->async_method_call( 3098b49ac873SJames Feist [health](const boost::system::error_code ec, 3099b49ac873SJames Feist std::vector<std::string>& resp) { 3100b49ac873SJames Feist if (ec) 3101b49ac873SJames Feist { 3102b49ac873SJames Feist // no inventory 3103b49ac873SJames Feist return; 3104b49ac873SJames Feist } 3105b49ac873SJames Feist 3106b49ac873SJames Feist health->inventory = std::move(resp); 3107b49ac873SJames Feist }, 3108b49ac873SJames Feist "xyz.openbmc_project.ObjectMapper", 3109b49ac873SJames Feist "/xyz/openbmc_project/object_mapper", 3110b49ac873SJames Feist "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/", 3111b49ac873SJames Feist int32_t(0), inventoryForSystems); 3112b49ac873SJames Feist 3113b49ac873SJames Feist health->populate(); 3114b49ac873SJames Feist 31158d1b46d7Szhanghch05 getMainChassisId( 31168d1b46d7Szhanghch05 asyncResp, [](const std::string& chassisId, 31178d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3118c5d03ff4SJennifer Lee aRsp->res.jsonValue["Links"]["Chassis"] = { 3119c5d03ff4SJennifer Lee {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}}; 3120c5d03ff4SJennifer Lee }); 3121a3002228SAppaRao Puli 31229f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 31239f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3124a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 31255bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 31266c34de48SEd Tanous getHostState(asyncResp); 3127491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3128978b8803SAndrew Geissler getBootProgress(asyncResp); 3129adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "PCIeDevices"); 313051709ffdSYong Li getHostWatchdogTimer(asyncResp); 3131c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 31326bd5a8d2SGunnar Mills getAutomaticRetry(asyncResp); 3133c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3134a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3135a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3136a6349918SAppaRao Puli #endif 31371981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 31383a2d0424SChris Cain getPowerMode(asyncResp); 313937bbf98cSChris Cain getIdlePowerSaver(asyncResp); 31407e860f15SJohn Edward Broadbent }); 31417e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 3142ed398213SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 31437e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 31447e860f15SJohn Edward Broadbent [](const crow::Request& req, 31457e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 31469f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3147cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 3148491d8ee7SSantosh Puranik std::optional<nlohmann::json> bootProps; 3149c45f0082SYong Li std::optional<nlohmann::json> wdtTimerProps; 315098e386ecSGunnar Mills std::optional<std::string> assetTag; 3151c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 31523a2d0424SChris Cain std::optional<std::string> powerMode; 315337bbf98cSChris Cain std::optional<nlohmann::json> ipsProps; 31549f8bfa7cSGunnar Mills if (!json_util::readJson( 31558d1b46d7Szhanghch05 req, asyncResp->res, "IndicatorLED", indicatorLed, 31567e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 31577e860f15SJohn Edward Broadbent "Boot", bootProps, "WatchdogTimer", wdtTimerProps, 31587e860f15SJohn Edward Broadbent "PowerRestorePolicy", powerRestorePolicy, "AssetTag", 315937bbf98cSChris Cain assetTag, "PowerMode", powerMode, "IdlePowerSaver", 316037bbf98cSChris Cain ipsProps)) 31616617338dSEd Tanous { 31626617338dSEd Tanous return; 31636617338dSEd Tanous } 3164491d8ee7SSantosh Puranik 31658d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3166c45f0082SYong Li 316798e386ecSGunnar Mills if (assetTag) 316898e386ecSGunnar Mills { 316998e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 317098e386ecSGunnar Mills } 317198e386ecSGunnar Mills 3172c45f0082SYong Li if (wdtTimerProps) 3173c45f0082SYong Li { 3174c45f0082SYong Li std::optional<bool> wdtEnable; 3175c45f0082SYong Li std::optional<std::string> wdtTimeOutAction; 3176c45f0082SYong Li 3177c45f0082SYong Li if (!json_util::readJson(*wdtTimerProps, asyncResp->res, 3178c45f0082SYong Li "FunctionEnabled", wdtEnable, 3179c45f0082SYong Li "TimeoutAction", wdtTimeOutAction)) 3180c45f0082SYong Li { 3181c45f0082SYong Li return; 3182c45f0082SYong Li } 3183f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3184c45f0082SYong Li } 3185c45f0082SYong Li 3186491d8ee7SSantosh Puranik if (bootProps) 3187491d8ee7SSantosh Puranik { 3188491d8ee7SSantosh Puranik std::optional<std::string> bootSource; 3189cd9a4666SKonstantin Aladyshev std::optional<std::string> bootType; 3190491d8ee7SSantosh Puranik std::optional<std::string> bootEnable; 319169f35306SGunnar Mills std::optional<std::string> automaticRetryConfig; 3192ac7e1e0bSAli Ahmed std::optional<bool> trustedModuleRequiredToBoot; 3193491d8ee7SSantosh Puranik 319469f35306SGunnar Mills if (!json_util::readJson( 31957e860f15SJohn Edward Broadbent *bootProps, asyncResp->res, 31967e860f15SJohn Edward Broadbent "BootSourceOverrideTarget", bootSource, 3197cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode", bootType, 31987e860f15SJohn Edward Broadbent "BootSourceOverrideEnabled", bootEnable, 3199ac7e1e0bSAli Ahmed "AutomaticRetryConfig", automaticRetryConfig, 3200ac7e1e0bSAli Ahmed "TrustedModuleRequiredToBoot", 3201ac7e1e0bSAli Ahmed trustedModuleRequiredToBoot)) 3202491d8ee7SSantosh Puranik { 3203491d8ee7SSantosh Puranik return; 3204491d8ee7SSantosh Puranik } 3205c21865c4SKonstantin Aladyshev 3206cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 320769f35306SGunnar Mills { 3208c21865c4SKonstantin Aladyshev setBootProperties(asyncResp, bootSource, bootType, 3209c21865c4SKonstantin Aladyshev bootEnable); 3210491d8ee7SSantosh Puranik } 321169f35306SGunnar Mills if (automaticRetryConfig) 321269f35306SGunnar Mills { 3213f23b7296SEd Tanous setAutomaticRetry(asyncResp, *automaticRetryConfig); 321469f35306SGunnar Mills } 3215ac7e1e0bSAli Ahmed 3216ac7e1e0bSAli Ahmed if (trustedModuleRequiredToBoot) 3217ac7e1e0bSAli Ahmed { 3218ac7e1e0bSAli Ahmed setTrustedModuleRequiredToBoot( 3219ac7e1e0bSAli Ahmed asyncResp, *trustedModuleRequiredToBoot); 3220ac7e1e0bSAli Ahmed } 322169f35306SGunnar Mills } 3222265c1602SJohnathan Mantey 32239f8bfa7cSGunnar Mills if (locationIndicatorActive) 32249f8bfa7cSGunnar Mills { 32257e860f15SJohn Edward Broadbent setLocationIndicatorActive(asyncResp, 32267e860f15SJohn Edward Broadbent *locationIndicatorActive); 32279f8bfa7cSGunnar Mills } 32289f8bfa7cSGunnar Mills 32297e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32307e860f15SJohn Edward Broadbent // passed 32319712f8acSEd Tanous if (indicatorLed) 32326617338dSEd Tanous { 3233f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 32347e860f15SJohn Edward Broadbent asyncResp->res.addHeader( 32357e860f15SJohn Edward Broadbent boost::beast::http::field::warning, 3236d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3237d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32386617338dSEd Tanous } 3239c6a620f2SGeorge Liu 3240c6a620f2SGeorge Liu if (powerRestorePolicy) 3241c6a620f2SGeorge Liu { 32424e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3243c6a620f2SGeorge Liu } 32443a2d0424SChris Cain 32453a2d0424SChris Cain if (powerMode) 32463a2d0424SChris Cain { 32473a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32483a2d0424SChris Cain } 324937bbf98cSChris Cain 325037bbf98cSChris Cain if (ipsProps) 325137bbf98cSChris Cain { 325237bbf98cSChris Cain std::optional<bool> ipsEnable; 325337bbf98cSChris Cain std::optional<uint8_t> ipsEnterUtil; 325437bbf98cSChris Cain std::optional<uint64_t> ipsEnterTime; 325537bbf98cSChris Cain std::optional<uint8_t> ipsExitUtil; 325637bbf98cSChris Cain std::optional<uint64_t> ipsExitTime; 325737bbf98cSChris Cain 325837bbf98cSChris Cain if (!json_util::readJson( 325937bbf98cSChris Cain *ipsProps, asyncResp->res, "Enabled", ipsEnable, 326037bbf98cSChris Cain "EnterUtilizationPercent", ipsEnterUtil, 326137bbf98cSChris Cain "EnterDwellTimeSeconds", ipsEnterTime, 326237bbf98cSChris Cain "ExitUtilizationPercent", ipsExitUtil, 326337bbf98cSChris Cain "ExitDwellTimeSeconds", ipsExitTime)) 326437bbf98cSChris Cain { 326537bbf98cSChris Cain return; 326637bbf98cSChris Cain } 326737bbf98cSChris Cain setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, 326837bbf98cSChris Cain ipsEnterTime, ipsExitUtil, ipsExitTime); 326937bbf98cSChris Cain } 32707e860f15SJohn Edward Broadbent }); 3271c5b2abe0SLewanczyk, Dawid } 32721cb1a9e6SAppaRao Puli 32731cb1a9e6SAppaRao Puli /** 32741cb1a9e6SAppaRao Puli * SystemResetActionInfo derived class for delivering Computer Systems 32751cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 32761cb1a9e6SAppaRao Puli */ 32777e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app) 32781cb1a9e6SAppaRao Puli { 32791cb1a9e6SAppaRao Puli 32801cb1a9e6SAppaRao Puli /** 32811cb1a9e6SAppaRao Puli * Functions triggers appropriate requests on DBus 32821cb1a9e6SAppaRao Puli */ 32837e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/") 3284ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 32857e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 32867e860f15SJohn Edward Broadbent [](const crow::Request&, 32877e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 32888d1b46d7Szhanghch05 asyncResp->res.jsonValue = { 32891cb1a9e6SAppaRao Puli {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"}, 32901cb1a9e6SAppaRao Puli {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"}, 32911cb1a9e6SAppaRao Puli {"Name", "Reset Action Info"}, 32921cb1a9e6SAppaRao Puli {"Id", "ResetActionInfo"}, 32931cb1a9e6SAppaRao Puli {"Parameters", 32941cb1a9e6SAppaRao Puli {{{"Name", "ResetType"}, 32951cb1a9e6SAppaRao Puli {"Required", true}, 32961cb1a9e6SAppaRao Puli {"DataType", "String"}, 32971cb1a9e6SAppaRao Puli {"AllowableValues", 32987e860f15SJohn Edward Broadbent {"On", "ForceOff", "ForceOn", "ForceRestart", 32997e860f15SJohn Edward Broadbent "GracefulRestart", "GracefulShutdown", "PowerCycle", 33007e860f15SJohn Edward Broadbent "Nmi"}}}}}}; 33017e860f15SJohn Edward Broadbent }); 33021cb1a9e6SAppaRao Puli } 3303c5b2abe0SLewanczyk, Dawid } // namespace redfish 3304