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 14257e8c9beSAlpana Kumari /* 143c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 144c5b2abe0SLewanczyk, Dawid * 145c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 1468f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 147c5b2abe0SLewanczyk, Dawid * 148c5b2abe0SLewanczyk, Dawid * @return None. 149c5b2abe0SLewanczyk, Dawid */ 150b5a76932SEd Tanous inline void 1518d1b46d7Szhanghch05 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 152b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 1531abe55efSEd Tanous { 15455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 1559d3ae10eSAlpana Kumari 15655c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 1575bc2dc8eSJames Feist [aResp, systemHealth]( 158c5b2abe0SLewanczyk, Dawid const boost::system::error_code ec, 159c5b2abe0SLewanczyk, Dawid const std::vector<std::pair< 1606c34de48SEd Tanous std::string, 1611214b7e7SGunnar Mills std::vector<std::pair<std::string, std::vector<std::string>>>>>& 1621214b7e7SGunnar Mills subtree) { 1631abe55efSEd Tanous if (ec) 1641abe55efSEd Tanous { 16555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 166f12894f8SJason M. Bills messages::internalError(aResp->res); 167c5b2abe0SLewanczyk, Dawid return; 168c5b2abe0SLewanczyk, Dawid } 169c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 1706c34de48SEd Tanous for (const std::pair<std::string, 1716c34de48SEd Tanous std::vector<std::pair< 1721214b7e7SGunnar Mills std::string, std::vector<std::string>>>>& 1731214b7e7SGunnar Mills object : subtree) 1741abe55efSEd Tanous { 175c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 17655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 1771abe55efSEd Tanous const std::vector< 1781214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 1791214b7e7SGunnar Mills connectionNames = object.second; 1801abe55efSEd Tanous if (connectionNames.size() < 1) 1811abe55efSEd Tanous { 182c5b2abe0SLewanczyk, Dawid continue; 183c5b2abe0SLewanczyk, Dawid } 184029573d4SEd Tanous 1855bc2dc8eSJames Feist auto memoryHealth = std::make_shared<HealthPopulate>( 1865bc2dc8eSJames Feist aResp, aResp->res.jsonValue["MemorySummary"]["Status"]); 1875bc2dc8eSJames Feist 1885bc2dc8eSJames Feist auto cpuHealth = std::make_shared<HealthPopulate>( 1895bc2dc8eSJames Feist aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]); 1905bc2dc8eSJames Feist 1915bc2dc8eSJames Feist systemHealth->children.emplace_back(memoryHealth); 1925bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 1935bc2dc8eSJames Feist 1946c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 1956c34de48SEd Tanous // BiosVer 19604a258f4SEd Tanous for (const auto& connection : connectionNames) 1971abe55efSEd Tanous { 19804a258f4SEd Tanous for (const auto& interfaceName : connection.second) 1991abe55efSEd Tanous { 20004a258f4SEd Tanous if (interfaceName == 20104a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 2021abe55efSEd Tanous { 2031abe55efSEd Tanous BMCWEB_LOG_DEBUG 20404a258f4SEd Tanous << "Found Dimm, now get its properties."; 2059d3ae10eSAlpana Kumari 20655c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 2079d3ae10eSAlpana Kumari [aResp, service{connection.first}, 208f23b7296SEd Tanous path](const boost::system::error_code ec2, 2096c34de48SEd Tanous const std::vector< 2101214b7e7SGunnar Mills std::pair<std::string, VariantType>>& 2111214b7e7SGunnar Mills properties) { 212cb13a392SEd Tanous if (ec2) 2131abe55efSEd Tanous { 2141abe55efSEd Tanous BMCWEB_LOG_ERROR 215cb13a392SEd Tanous << "DBUS response error " << ec2; 216f12894f8SJason M. Bills messages::internalError(aResp->res); 217c5b2abe0SLewanczyk, Dawid return; 218c5b2abe0SLewanczyk, Dawid } 2196c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 2206c34de48SEd Tanous << properties.size() 221c5b2abe0SLewanczyk, Dawid << " Dimm properties."; 2229d3ae10eSAlpana Kumari 2239d3ae10eSAlpana Kumari if (properties.size() > 0) 2249d3ae10eSAlpana Kumari { 22504a258f4SEd Tanous for (const std::pair<std::string, 2261214b7e7SGunnar Mills VariantType>& 2271214b7e7SGunnar Mills property : properties) 2281abe55efSEd Tanous { 2295fd7ba65SCheng C Yang if (property.first != 2305fd7ba65SCheng C Yang "MemorySizeInKB") 2311abe55efSEd Tanous { 2325fd7ba65SCheng C Yang continue; 2335fd7ba65SCheng C Yang } 2345fd7ba65SCheng C Yang const uint32_t* value = 2358d78b7a9SPatrick Williams std::get_if<uint32_t>( 2361b6b96c5SEd Tanous &property.second); 2375fd7ba65SCheng C Yang if (value == nullptr) 2381abe55efSEd Tanous { 2395fd7ba65SCheng C Yang BMCWEB_LOG_DEBUG 2405fd7ba65SCheng C Yang << "Find incorrect type of " 2415fd7ba65SCheng C Yang "MemorySize"; 2425fd7ba65SCheng C Yang continue; 2435fd7ba65SCheng C Yang } 2445fd7ba65SCheng C Yang nlohmann::json& totalMemory = 2455fd7ba65SCheng C Yang aResp->res 2465fd7ba65SCheng C Yang .jsonValue["MemorySummar" 2475fd7ba65SCheng C Yang "y"] 2485fd7ba65SCheng C Yang ["TotalSystemMe" 2495fd7ba65SCheng C Yang "moryGiB"]; 2505fd7ba65SCheng C Yang uint64_t* preValue = 2515fd7ba65SCheng C Yang totalMemory 2525fd7ba65SCheng C Yang .get_ptr<uint64_t*>(); 2535fd7ba65SCheng C Yang if (preValue == nullptr) 2545fd7ba65SCheng C Yang { 2555fd7ba65SCheng C Yang continue; 2565fd7ba65SCheng C Yang } 2575fd7ba65SCheng C Yang aResp->res 2585fd7ba65SCheng C Yang .jsonValue["MemorySummary"] 2596c34de48SEd Tanous ["TotalSystemMemoryGi" 2605fd7ba65SCheng C Yang "B"] = 2615fd7ba65SCheng C Yang *value / (1024 * 1024) + 2625fd7ba65SCheng C Yang *preValue; 2635fd7ba65SCheng C Yang aResp->res 2645fd7ba65SCheng C Yang .jsonValue["MemorySummary"] 2659d3ae10eSAlpana Kumari ["Status"]["State"] = 2661abe55efSEd Tanous "Enabled"; 267c5b2abe0SLewanczyk, Dawid } 268c5b2abe0SLewanczyk, Dawid } 2699d3ae10eSAlpana Kumari else 2709d3ae10eSAlpana Kumari { 2719d3ae10eSAlpana Kumari auto getDimmProperties = 2729d3ae10eSAlpana Kumari [aResp]( 2739d3ae10eSAlpana Kumari const boost::system::error_code 274cb13a392SEd Tanous ec3, 2751214b7e7SGunnar Mills const std::variant<bool>& 2761214b7e7SGunnar Mills dimmState) { 277cb13a392SEd Tanous if (ec3) 2789d3ae10eSAlpana Kumari { 2799d3ae10eSAlpana Kumari BMCWEB_LOG_ERROR 2809d3ae10eSAlpana Kumari << "DBUS response " 2819d3ae10eSAlpana Kumari "error " 282cb13a392SEd Tanous << ec3; 2839d3ae10eSAlpana Kumari return; 2849d3ae10eSAlpana Kumari } 2859d3ae10eSAlpana Kumari updateDimmProperties(aResp, 2869d3ae10eSAlpana Kumari dimmState); 2879d3ae10eSAlpana Kumari }; 2889d3ae10eSAlpana Kumari crow::connections::systemBus 2899d3ae10eSAlpana Kumari ->async_method_call( 2909d3ae10eSAlpana Kumari std::move(getDimmProperties), 2919d3ae10eSAlpana Kumari service, path, 2929d3ae10eSAlpana Kumari "org.freedesktop.DBus." 2939d3ae10eSAlpana Kumari "Properties", 2949d3ae10eSAlpana Kumari "Get", 2959d3ae10eSAlpana Kumari "xyz.openbmc_project.State." 2969d3ae10eSAlpana Kumari "Decorator.OperationalStatus", 2979d3ae10eSAlpana Kumari "Functional"); 2989d3ae10eSAlpana Kumari } 299c5b2abe0SLewanczyk, Dawid }, 30004a258f4SEd Tanous connection.first, path, 3016c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 3026c34de48SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm"); 3035bc2dc8eSJames Feist 3045bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 3051abe55efSEd Tanous } 30604a258f4SEd Tanous else if (interfaceName == 30704a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 3081abe55efSEd Tanous { 3091abe55efSEd Tanous BMCWEB_LOG_DEBUG 31004a258f4SEd Tanous << "Found Cpu, now get its properties."; 31157e8c9beSAlpana Kumari 312a0803efaSEd Tanous crow::connections::systemBus->async_method_call( 31357e8c9beSAlpana Kumari [aResp, service{connection.first}, 314f23b7296SEd Tanous path](const boost::system::error_code ec2, 3156c34de48SEd Tanous const std::vector< 3161214b7e7SGunnar Mills std::pair<std::string, VariantType>>& 3171214b7e7SGunnar Mills properties) { 318cb13a392SEd Tanous if (ec2) 3191abe55efSEd Tanous { 3201abe55efSEd Tanous BMCWEB_LOG_ERROR 321cb13a392SEd Tanous << "DBUS response error " << ec2; 322f12894f8SJason M. Bills messages::internalError(aResp->res); 323c5b2abe0SLewanczyk, Dawid return; 324c5b2abe0SLewanczyk, Dawid } 3256c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 3266c34de48SEd Tanous << properties.size() 327c5b2abe0SLewanczyk, Dawid << " Cpu properties."; 32857e8c9beSAlpana Kumari 32957e8c9beSAlpana Kumari if (properties.size() > 0) 33057e8c9beSAlpana Kumari { 3319cf21522SZhikui Ren const uint64_t* processorId = nullptr; 332029cc1f4SZhikui Ren const std::string* procFamily = nullptr; 333029cc1f4SZhikui Ren nlohmann::json& procSummary = 334029cc1f4SZhikui Ren aResp->res.jsonValue["ProcessorSumm" 33504a258f4SEd Tanous "ary"]; 33604a258f4SEd Tanous nlohmann::json& procCount = 33704a258f4SEd Tanous procSummary["Count"]; 338b4b9595aSJames Feist 339029cc1f4SZhikui Ren auto procCountPtr = procCount.get_ptr< 340b4b9595aSJames Feist nlohmann::json:: 3411214b7e7SGunnar Mills number_integer_t*>(); 342029cc1f4SZhikui Ren if (procCountPtr == nullptr) 343b4b9595aSJames Feist { 344029cc1f4SZhikui Ren messages::internalError(aResp->res); 345029cc1f4SZhikui Ren return; 346029cc1f4SZhikui Ren } 347029cc1f4SZhikui Ren for (const auto& property : properties) 348029cc1f4SZhikui Ren { 349029cc1f4SZhikui Ren 3509cf21522SZhikui Ren if (property.first == "Id") 351029cc1f4SZhikui Ren { 352029cc1f4SZhikui Ren processorId = 3539cf21522SZhikui Ren std::get_if<uint64_t>( 354029cc1f4SZhikui Ren &property.second); 355029cc1f4SZhikui Ren if (nullptr != procFamily) 3563174e4dfSEd Tanous { 357029cc1f4SZhikui Ren break; 3583174e4dfSEd Tanous } 359029cc1f4SZhikui Ren continue; 360029cc1f4SZhikui Ren } 361029cc1f4SZhikui Ren 3629cf21522SZhikui Ren if (property.first == "Family") 363029cc1f4SZhikui Ren { 364029cc1f4SZhikui Ren procFamily = 365029cc1f4SZhikui Ren std::get_if<std::string>( 366029cc1f4SZhikui Ren &property.second); 367029cc1f4SZhikui Ren if (nullptr != processorId) 3683174e4dfSEd Tanous { 369029cc1f4SZhikui Ren break; 3703174e4dfSEd Tanous } 371029cc1f4SZhikui Ren continue; 372029cc1f4SZhikui Ren } 373029cc1f4SZhikui Ren } 374029cc1f4SZhikui Ren 375029cc1f4SZhikui Ren if (procFamily != nullptr && 376029cc1f4SZhikui Ren processorId != nullptr) 377029cc1f4SZhikui Ren { 378029cc1f4SZhikui Ren if (procCountPtr != nullptr && 379029cc1f4SZhikui Ren *processorId != 0) 380029cc1f4SZhikui Ren { 381b4b9595aSJames Feist *procCountPtr += 1; 382029cc1f4SZhikui Ren procSummary["Status"]["State"] = 383c5b2abe0SLewanczyk, Dawid "Enabled"; 384029cc1f4SZhikui Ren 38557e8c9beSAlpana Kumari procSummary["Model"] = 386029cc1f4SZhikui Ren *procFamily; 387c5b2abe0SLewanczyk, Dawid } 388c5b2abe0SLewanczyk, Dawid } 38957e8c9beSAlpana Kumari } 39057e8c9beSAlpana Kumari else 39157e8c9beSAlpana Kumari { 39257e8c9beSAlpana Kumari auto getCpuPresenceState = 39357e8c9beSAlpana Kumari [aResp]( 39457e8c9beSAlpana Kumari const boost::system::error_code 395cb13a392SEd Tanous ec3, 3961214b7e7SGunnar Mills const std::variant<bool>& 3971214b7e7SGunnar Mills cpuPresenceCheck) { 398cb13a392SEd Tanous if (ec3) 39957e8c9beSAlpana Kumari { 40057e8c9beSAlpana Kumari BMCWEB_LOG_ERROR 40157e8c9beSAlpana Kumari << "DBUS response " 40257e8c9beSAlpana Kumari "error " 403cb13a392SEd Tanous << ec3; 40457e8c9beSAlpana Kumari return; 40557e8c9beSAlpana Kumari } 40657e8c9beSAlpana Kumari modifyCpuPresenceState( 40757e8c9beSAlpana Kumari aResp, cpuPresenceCheck); 40857e8c9beSAlpana Kumari }; 40957e8c9beSAlpana Kumari 41057e8c9beSAlpana Kumari auto getCpuFunctionalState = 41157e8c9beSAlpana Kumari [aResp]( 41257e8c9beSAlpana Kumari const boost::system::error_code 413cb13a392SEd Tanous ec3, 4141214b7e7SGunnar Mills const std::variant<bool>& 4151214b7e7SGunnar Mills cpuFunctionalCheck) { 416cb13a392SEd Tanous if (ec3) 41757e8c9beSAlpana Kumari { 41857e8c9beSAlpana Kumari BMCWEB_LOG_ERROR 41957e8c9beSAlpana Kumari << "DBUS response " 42057e8c9beSAlpana Kumari "error " 421cb13a392SEd Tanous << ec3; 42257e8c9beSAlpana Kumari return; 42357e8c9beSAlpana Kumari } 42457e8c9beSAlpana Kumari modifyCpuFunctionalState( 42557e8c9beSAlpana Kumari aResp, cpuFunctionalCheck); 42657e8c9beSAlpana Kumari }; 42757e8c9beSAlpana Kumari // Get the Presence of CPU 42857e8c9beSAlpana Kumari crow::connections::systemBus 42957e8c9beSAlpana Kumari ->async_method_call( 43057e8c9beSAlpana Kumari std::move(getCpuPresenceState), 43157e8c9beSAlpana Kumari service, path, 43257e8c9beSAlpana Kumari "org.freedesktop.DBus." 43357e8c9beSAlpana Kumari "Properties", 43457e8c9beSAlpana Kumari "Get", 43557e8c9beSAlpana Kumari "xyz.openbmc_project.Inventory." 43657e8c9beSAlpana Kumari "Item", 43757e8c9beSAlpana Kumari "Present"); 43857e8c9beSAlpana Kumari 43957e8c9beSAlpana Kumari // Get the Functional State 44057e8c9beSAlpana Kumari crow::connections::systemBus 44157e8c9beSAlpana Kumari ->async_method_call( 44257e8c9beSAlpana Kumari std::move( 44357e8c9beSAlpana Kumari getCpuFunctionalState), 44457e8c9beSAlpana Kumari service, path, 44557e8c9beSAlpana Kumari "org.freedesktop.DBus." 44657e8c9beSAlpana Kumari "Properties", 44757e8c9beSAlpana Kumari "Get", 44857e8c9beSAlpana Kumari "xyz.openbmc_project.State." 44957e8c9beSAlpana Kumari "Decorator." 45057e8c9beSAlpana Kumari "OperationalStatus", 45157e8c9beSAlpana Kumari "Functional"); 45257e8c9beSAlpana Kumari 45357e8c9beSAlpana Kumari // Get the MODEL from 45457e8c9beSAlpana Kumari // xyz.openbmc_project.Inventory.Decorator.Asset 45557e8c9beSAlpana Kumari // support it later as Model is Empty 45657e8c9beSAlpana Kumari // currently. 45757e8c9beSAlpana Kumari } 458c5b2abe0SLewanczyk, Dawid }, 45904a258f4SEd Tanous connection.first, path, 4606c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 4616c34de48SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu"); 4625bc2dc8eSJames Feist 4635bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4641abe55efSEd Tanous } 46504a258f4SEd Tanous else if (interfaceName == 46604a258f4SEd Tanous "xyz.openbmc_project.Common.UUID") 4671abe55efSEd Tanous { 4681abe55efSEd Tanous BMCWEB_LOG_DEBUG 46904a258f4SEd Tanous << "Found UUID, now get its properties."; 47055c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 4711214b7e7SGunnar Mills [aResp]( 472cb13a392SEd Tanous const boost::system::error_code ec3, 4736c34de48SEd Tanous const std::vector< 4741214b7e7SGunnar Mills std::pair<std::string, VariantType>>& 4751214b7e7SGunnar Mills properties) { 476cb13a392SEd Tanous if (ec3) 4771abe55efSEd Tanous { 4781abe55efSEd Tanous BMCWEB_LOG_DEBUG 479cb13a392SEd Tanous << "DBUS response error " << ec3; 480f12894f8SJason M. Bills messages::internalError(aResp->res); 481c5b2abe0SLewanczyk, Dawid return; 482c5b2abe0SLewanczyk, Dawid } 4836c34de48SEd Tanous BMCWEB_LOG_DEBUG << "Got " 4846c34de48SEd Tanous << properties.size() 485c5b2abe0SLewanczyk, Dawid << " UUID properties."; 4861abe55efSEd Tanous for (const std::pair<std::string, 4871214b7e7SGunnar Mills VariantType>& 4881214b7e7SGunnar Mills property : properties) 4891abe55efSEd Tanous { 49004a258f4SEd Tanous if (property.first == "UUID") 4911abe55efSEd Tanous { 492c5b2abe0SLewanczyk, Dawid const std::string* value = 4938d78b7a9SPatrick Williams std::get_if<std::string>( 4941b6b96c5SEd Tanous &property.second); 49504a258f4SEd Tanous 4961abe55efSEd Tanous if (value != nullptr) 4971abe55efSEd Tanous { 498029573d4SEd Tanous std::string valueStr = *value; 49904a258f4SEd Tanous if (valueStr.size() == 32) 5001abe55efSEd Tanous { 501029573d4SEd Tanous valueStr.insert(8, 1, '-'); 502029573d4SEd Tanous valueStr.insert(13, 1, '-'); 503029573d4SEd Tanous valueStr.insert(18, 1, '-'); 504029573d4SEd Tanous valueStr.insert(23, 1, '-'); 50504a258f4SEd Tanous } 506029573d4SEd Tanous BMCWEB_LOG_DEBUG << "UUID = " 50704a258f4SEd Tanous << valueStr; 508029573d4SEd Tanous aResp->res.jsonValue["UUID"] = 50904a258f4SEd Tanous valueStr; 510c5b2abe0SLewanczyk, Dawid } 511c5b2abe0SLewanczyk, Dawid } 512c5b2abe0SLewanczyk, Dawid } 513c5b2abe0SLewanczyk, Dawid }, 51404a258f4SEd Tanous connection.first, path, 5156c34de48SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 5161abe55efSEd Tanous "xyz.openbmc_project.Common.UUID"); 517c5b2abe0SLewanczyk, Dawid } 518029573d4SEd Tanous else if (interfaceName == 519029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 5201abe55efSEd Tanous { 521029573d4SEd Tanous crow::connections::systemBus->async_method_call( 5221214b7e7SGunnar Mills [aResp]( 523cb13a392SEd Tanous const boost::system::error_code ec2, 524029573d4SEd Tanous const std::vector< 5251214b7e7SGunnar Mills std::pair<std::string, VariantType>>& 5261214b7e7SGunnar Mills propertiesList) { 527cb13a392SEd Tanous if (ec2) 528029573d4SEd Tanous { 529e4a4b9a9SJames Feist // doesn't have to include this 530e4a4b9a9SJames Feist // interface 531029573d4SEd Tanous return; 532029573d4SEd Tanous } 533698654b6SGunnar Mills BMCWEB_LOG_DEBUG 534698654b6SGunnar Mills << "Got " << propertiesList.size() 535029573d4SEd Tanous << " properties for system"; 536029573d4SEd Tanous for (const std::pair<std::string, 5371214b7e7SGunnar Mills VariantType>& 5381214b7e7SGunnar Mills property : propertiesList) 539029573d4SEd Tanous { 540fc5afcf9Sbeccabroek const std::string& propertyName = 541fc5afcf9Sbeccabroek property.first; 542fc5afcf9Sbeccabroek if ((propertyName == "PartNumber") || 543fc5afcf9Sbeccabroek (propertyName == "SerialNumber") || 544fc5afcf9Sbeccabroek (propertyName == "Manufacturer") || 5455235d964SSunnySrivastava1984 (propertyName == "Model") || 5465235d964SSunnySrivastava1984 (propertyName == "SubModel")) 547fc5afcf9Sbeccabroek { 548029573d4SEd Tanous const std::string* value = 549fc5afcf9Sbeccabroek std::get_if<std::string>( 550029573d4SEd Tanous &property.second); 551029573d4SEd Tanous if (value != nullptr) 552029573d4SEd Tanous { 553029573d4SEd Tanous aResp->res 554fc5afcf9Sbeccabroek .jsonValue[propertyName] = 555029573d4SEd Tanous *value; 556029573d4SEd Tanous } 557029573d4SEd Tanous } 558fc5afcf9Sbeccabroek } 559c1e236a6SGunnar Mills 560cb7e1e7bSAndrew Geissler // Grab the bios version 561f97ddba7SGunnar Mills fw_util::populateFirmwareInformation( 562cb7e1e7bSAndrew Geissler aResp, fw_util::biosPurpose, 56372d566d9SGunnar Mills "BiosVersion", false); 564029573d4SEd Tanous }, 565029573d4SEd Tanous connection.first, path, 566029573d4SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 567029573d4SEd Tanous "xyz.openbmc_project.Inventory.Decorator." 568029573d4SEd Tanous "Asset"); 569e4a4b9a9SJames Feist 570e4a4b9a9SJames Feist crow::connections::systemBus->async_method_call( 571e4a4b9a9SJames Feist [aResp]( 572cb13a392SEd Tanous const boost::system::error_code ec2, 573e4a4b9a9SJames Feist const std::variant<std::string>& property) { 574cb13a392SEd Tanous if (ec2) 575e4a4b9a9SJames Feist { 576e4a4b9a9SJames Feist // doesn't have to include this 577e4a4b9a9SJames Feist // interface 578e4a4b9a9SJames Feist return; 579e4a4b9a9SJames Feist } 580e4a4b9a9SJames Feist 581e4a4b9a9SJames Feist const std::string* value = 582e4a4b9a9SJames Feist std::get_if<std::string>(&property); 583e4a4b9a9SJames Feist if (value != nullptr) 584e4a4b9a9SJames Feist { 585e4a4b9a9SJames Feist aResp->res.jsonValue["AssetTag"] = 586e4a4b9a9SJames Feist *value; 587e4a4b9a9SJames Feist } 588e4a4b9a9SJames Feist }, 589e4a4b9a9SJames Feist connection.first, path, 590e4a4b9a9SJames Feist "org.freedesktop.DBus.Properties", "Get", 591e4a4b9a9SJames Feist "xyz.openbmc_project.Inventory.Decorator." 592e4a4b9a9SJames Feist "AssetTag", 593e4a4b9a9SJames Feist "AssetTag"); 594029573d4SEd Tanous } 595029573d4SEd Tanous } 596029573d4SEd Tanous } 597c5b2abe0SLewanczyk, Dawid } 598c5b2abe0SLewanczyk, Dawid }, 599c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", 600c5b2abe0SLewanczyk, Dawid "/xyz/openbmc_project/object_mapper", 601c5b2abe0SLewanczyk, Dawid "xyz.openbmc_project.ObjectMapper", "GetSubTree", 6026617338dSEd Tanous "/xyz/openbmc_project/inventory", int32_t(0), 6036617338dSEd Tanous std::array<const char*, 5>{ 6046617338dSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset", 6056617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu", 6066617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm", 6076617338dSEd Tanous "xyz.openbmc_project.Inventory.Item.System", 6086617338dSEd Tanous "xyz.openbmc_project.Common.UUID", 6096617338dSEd Tanous }); 610c5b2abe0SLewanczyk, Dawid } 611c5b2abe0SLewanczyk, Dawid 612c5b2abe0SLewanczyk, Dawid /** 613c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 614c5b2abe0SLewanczyk, Dawid * 615c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 616c5b2abe0SLewanczyk, Dawid * 617c5b2abe0SLewanczyk, Dawid * @return None. 618c5b2abe0SLewanczyk, Dawid */ 6198d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 6201abe55efSEd Tanous { 62155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 62255c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 623c5d03ff4SJennifer Lee [aResp](const boost::system::error_code ec, 624abf2add6SEd Tanous const std::variant<std::string>& hostState) { 6251abe55efSEd Tanous if (ec) 6261abe55efSEd Tanous { 62755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 628f12894f8SJason M. Bills messages::internalError(aResp->res); 629c5b2abe0SLewanczyk, Dawid return; 630c5b2abe0SLewanczyk, Dawid } 6316617338dSEd Tanous 632abf2add6SEd Tanous const std::string* s = std::get_if<std::string>(&hostState); 63355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Host state: " << *s; 6346617338dSEd Tanous if (s != nullptr) 6351abe55efSEd Tanous { 636c5b2abe0SLewanczyk, Dawid // Verify Host State 63794732661SAndrew Geissler if (*s == "xyz.openbmc_project.State.Host.HostState.Running") 6381abe55efSEd Tanous { 63955c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 6406617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 6411abe55efSEd Tanous } 64283935af9SAndrew Geissler else if (*s == "xyz.openbmc_project.State.Host.HostState." 6438c888608SGunnar Mills "Quiesced") 6448c888608SGunnar Mills { 6458c888608SGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 6468c888608SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6478c888608SGunnar Mills } 6488c888608SGunnar Mills else if (*s == "xyz.openbmc_project.State.Host.HostState." 64983935af9SAndrew Geissler "DiagnosticMode") 65083935af9SAndrew Geissler { 65183935af9SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 65283935af9SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "InTest"; 65383935af9SAndrew Geissler } 6541a2a1437SAndrew Geissler else if (*s == "xyz.openbmc_project.State.Host.HostState." 6551a2a1437SAndrew Geissler "TransitioningToRunning") 6561a2a1437SAndrew Geissler { 6571a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOn"; 65815c27bf8SNoah Brewer aResp->res.jsonValue["Status"]["State"] = "Starting"; 6591a2a1437SAndrew Geissler } 6601a2a1437SAndrew Geissler else if (*s == "xyz.openbmc_project.State.Host.HostState." 6611a2a1437SAndrew Geissler "TransitioningToOff") 6621a2a1437SAndrew Geissler { 6631a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOff"; 6641a2a1437SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Disabled"; 6651a2a1437SAndrew Geissler } 6661abe55efSEd Tanous else 6671abe55efSEd Tanous { 66855c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 6696617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 670c5b2abe0SLewanczyk, Dawid } 671c5b2abe0SLewanczyk, Dawid } 672c5b2abe0SLewanczyk, Dawid }, 6736c34de48SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 6746617338dSEd Tanous "org.freedesktop.DBus.Properties", "Get", 6756617338dSEd Tanous "xyz.openbmc_project.State.Host", "CurrentHostState"); 676c5b2abe0SLewanczyk, Dawid } 677c5b2abe0SLewanczyk, Dawid 678c5b2abe0SLewanczyk, Dawid /** 679786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 680491d8ee7SSantosh Puranik * 681491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 682491d8ee7SSantosh Puranik * 683491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 684491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 685491d8ee7SSantosh Puranik */ 68623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 687491d8ee7SSantosh Puranik { 688491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 689491d8ee7SSantosh Puranik { 690491d8ee7SSantosh Puranik return "None"; 691491d8ee7SSantosh Puranik } 6923174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 693491d8ee7SSantosh Puranik { 694491d8ee7SSantosh Puranik return "Hdd"; 695491d8ee7SSantosh Puranik } 6963174e4dfSEd Tanous if (dbusSource == 697a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 698491d8ee7SSantosh Puranik { 699491d8ee7SSantosh Puranik return "Cd"; 700491d8ee7SSantosh Puranik } 7013174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 702491d8ee7SSantosh Puranik { 703491d8ee7SSantosh Puranik return "Pxe"; 704491d8ee7SSantosh Puranik } 7053174e4dfSEd Tanous if (dbusSource == 706944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 7079f16b2c1SJennifer Lee { 7089f16b2c1SJennifer Lee return "Usb"; 7099f16b2c1SJennifer Lee } 710491d8ee7SSantosh Puranik return ""; 711491d8ee7SSantosh Puranik } 712491d8ee7SSantosh Puranik 713491d8ee7SSantosh Puranik /** 714cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 715cd9a4666SKonstantin Aladyshev * 716cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 717cd9a4666SKonstantin Aladyshev * 718cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 719cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 720cd9a4666SKonstantin Aladyshev */ 721cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 722cd9a4666SKonstantin Aladyshev { 723cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 724cd9a4666SKonstantin Aladyshev { 725cd9a4666SKonstantin Aladyshev return "Legacy"; 726cd9a4666SKonstantin Aladyshev } 727cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 728cd9a4666SKonstantin Aladyshev { 729cd9a4666SKonstantin Aladyshev return "UEFI"; 730cd9a4666SKonstantin Aladyshev } 731cd9a4666SKonstantin Aladyshev return ""; 732cd9a4666SKonstantin Aladyshev } 733cd9a4666SKonstantin Aladyshev 734cd9a4666SKonstantin Aladyshev /** 735786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 736491d8ee7SSantosh Puranik * 737491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 738491d8ee7SSantosh Puranik * 739491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 740491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 741491d8ee7SSantosh Puranik */ 74223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 743491d8ee7SSantosh Puranik { 744491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 745491d8ee7SSantosh Puranik { 746491d8ee7SSantosh Puranik return "None"; 747491d8ee7SSantosh Puranik } 7483174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 749491d8ee7SSantosh Puranik { 750491d8ee7SSantosh Puranik return "Diags"; 751491d8ee7SSantosh Puranik } 7523174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 753491d8ee7SSantosh Puranik { 754491d8ee7SSantosh Puranik return "BiosSetup"; 755491d8ee7SSantosh Puranik } 756491d8ee7SSantosh Puranik return ""; 757491d8ee7SSantosh Puranik } 758491d8ee7SSantosh Puranik 759491d8ee7SSantosh Puranik /** 760786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 761491d8ee7SSantosh Puranik * 762491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 763944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 764944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 765491d8ee7SSantosh Puranik * 766944ffaf9SJohnathan Mantey * @return Integer error code. 767491d8ee7SSantosh Puranik */ 7688d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 769944ffaf9SJohnathan Mantey const std::string& rfSource, 770944ffaf9SJohnathan Mantey std::string& bootSource, std::string& bootMode) 771491d8ee7SSantosh Puranik { 772*c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 773*c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 774944ffaf9SJohnathan Mantey 775491d8ee7SSantosh Puranik if (rfSource == "None") 776491d8ee7SSantosh Puranik { 777944ffaf9SJohnathan Mantey return 0; 778491d8ee7SSantosh Puranik } 7793174e4dfSEd Tanous if (rfSource == "Pxe") 780491d8ee7SSantosh Puranik { 781944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 782944ffaf9SJohnathan Mantey } 783944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 784944ffaf9SJohnathan Mantey { 785944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 786944ffaf9SJohnathan Mantey } 787944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 788944ffaf9SJohnathan Mantey { 789944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 790944ffaf9SJohnathan Mantey } 791944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 792944ffaf9SJohnathan Mantey { 793944ffaf9SJohnathan Mantey bootSource = 794944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 795944ffaf9SJohnathan Mantey } 796944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 797944ffaf9SJohnathan Mantey { 798944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 799491d8ee7SSantosh Puranik } 8009f16b2c1SJennifer Lee else if (rfSource == "Usb") 8019f16b2c1SJennifer Lee { 802944ffaf9SJohnathan Mantey bootSource = 803944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8049f16b2c1SJennifer Lee } 805491d8ee7SSantosh Puranik else 806491d8ee7SSantosh Puranik { 807944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "Invalid property value for " 808944ffaf9SJohnathan Mantey "BootSourceOverrideTarget: " 809944ffaf9SJohnathan Mantey << bootSource; 810944ffaf9SJohnathan Mantey messages::propertyValueNotInList(aResp->res, rfSource, 811944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 812944ffaf9SJohnathan Mantey return -1; 813491d8ee7SSantosh Puranik } 814944ffaf9SJohnathan Mantey return 0; 815491d8ee7SSantosh Puranik } 8161981771bSAli Ahmed 817978b8803SAndrew Geissler /** 818978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 819978b8803SAndrew Geissler * 820978b8803SAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 821978b8803SAndrew Geissler * 822978b8803SAndrew Geissler * @return None. 823978b8803SAndrew Geissler */ 8248d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 825978b8803SAndrew Geissler { 826978b8803SAndrew Geissler crow::connections::systemBus->async_method_call( 827978b8803SAndrew Geissler [aResp](const boost::system::error_code ec, 828978b8803SAndrew Geissler const std::variant<std::string>& bootProgress) { 829978b8803SAndrew Geissler if (ec) 830978b8803SAndrew Geissler { 831978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 832978b8803SAndrew Geissler // not found 833978b8803SAndrew Geissler return; 834978b8803SAndrew Geissler } 835978b8803SAndrew Geissler 836978b8803SAndrew Geissler const std::string* bootProgressStr = 837978b8803SAndrew Geissler std::get_if<std::string>(&bootProgress); 838978b8803SAndrew Geissler 839978b8803SAndrew Geissler if (!bootProgressStr) 840978b8803SAndrew Geissler { 841978b8803SAndrew Geissler // Interface implemented but property not found, return error 842978b8803SAndrew Geissler // for that 843978b8803SAndrew Geissler messages::internalError(aResp->res); 844978b8803SAndrew Geissler return; 845978b8803SAndrew Geissler } 846978b8803SAndrew Geissler 847978b8803SAndrew Geissler BMCWEB_LOG_DEBUG << "Boot Progress: " << *bootProgressStr; 848978b8803SAndrew Geissler 849978b8803SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 850978b8803SAndrew Geissler // enum 851978b8803SAndrew Geissler std::string rfBpLastState = "None"; 852978b8803SAndrew Geissler if (*bootProgressStr == "xyz.openbmc_project.State.Boot.Progress." 853978b8803SAndrew Geissler "ProgressStages.Unspecified") 854978b8803SAndrew Geissler { 855978b8803SAndrew Geissler rfBpLastState = "None"; 856978b8803SAndrew Geissler } 857978b8803SAndrew Geissler else if (*bootProgressStr == 858978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 859978b8803SAndrew Geissler "PrimaryProcInit") 860978b8803SAndrew Geissler { 861978b8803SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 862978b8803SAndrew Geissler } 863978b8803SAndrew Geissler else if (*bootProgressStr == 864978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 865978b8803SAndrew Geissler "BusInit") 866978b8803SAndrew Geissler { 867978b8803SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 868978b8803SAndrew Geissler } 869978b8803SAndrew Geissler else if (*bootProgressStr == 870978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 871978b8803SAndrew Geissler "MemoryInit") 872978b8803SAndrew Geissler { 873978b8803SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 874978b8803SAndrew Geissler } 875978b8803SAndrew Geissler else if (*bootProgressStr == 876978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 877978b8803SAndrew Geissler "SecondaryProcInit") 878978b8803SAndrew Geissler { 879978b8803SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 880978b8803SAndrew Geissler } 881978b8803SAndrew Geissler else if (*bootProgressStr == 882978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 883978b8803SAndrew Geissler "PCIInit") 884978b8803SAndrew Geissler { 885978b8803SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 886978b8803SAndrew Geissler } 887978b8803SAndrew Geissler else if (*bootProgressStr == 888978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 889978b8803SAndrew Geissler "SystemInitComplete") 890978b8803SAndrew Geissler { 891978b8803SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 892978b8803SAndrew Geissler } 893978b8803SAndrew Geissler else if (*bootProgressStr == 894978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 895978b8803SAndrew Geissler "OSStart") 896978b8803SAndrew Geissler { 897978b8803SAndrew Geissler rfBpLastState = "OSBootStarted"; 898978b8803SAndrew Geissler } 899978b8803SAndrew Geissler else if (*bootProgressStr == 900978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 901978b8803SAndrew Geissler "OSRunning") 902978b8803SAndrew Geissler { 903978b8803SAndrew Geissler rfBpLastState = "OSRunning"; 904978b8803SAndrew Geissler } 905978b8803SAndrew Geissler else 906978b8803SAndrew Geissler { 907978b8803SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 908978b8803SAndrew Geissler << *bootProgressStr; 909978b8803SAndrew Geissler // Just return the default 910978b8803SAndrew Geissler } 911978b8803SAndrew Geissler 912978b8803SAndrew Geissler aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState; 913978b8803SAndrew Geissler }, 914978b8803SAndrew Geissler "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 915978b8803SAndrew Geissler "org.freedesktop.DBus.Properties", "Get", 916978b8803SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress", "BootProgress"); 917978b8803SAndrew Geissler } 918491d8ee7SSantosh Puranik 919491d8ee7SSantosh Puranik /** 920*c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 921cd9a4666SKonstantin Aladyshev * 922cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 923cd9a4666SKonstantin Aladyshev * 924cd9a4666SKonstantin Aladyshev * @return None. 925cd9a4666SKonstantin Aladyshev */ 926cd9a4666SKonstantin Aladyshev 927*c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 928cd9a4666SKonstantin Aladyshev { 929cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 930cd9a4666SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 931cd9a4666SKonstantin Aladyshev const std::variant<std::string>& bootType) { 932cd9a4666SKonstantin Aladyshev if (ec) 933cd9a4666SKonstantin Aladyshev { 934cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 935cd9a4666SKonstantin Aladyshev return; 936cd9a4666SKonstantin Aladyshev } 937cd9a4666SKonstantin Aladyshev 938cd9a4666SKonstantin Aladyshev const std::string* bootTypeStr = 939cd9a4666SKonstantin Aladyshev std::get_if<std::string>(&bootType); 940cd9a4666SKonstantin Aladyshev 941cd9a4666SKonstantin Aladyshev if (!bootTypeStr) 942cd9a4666SKonstantin Aladyshev { 943cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 944cd9a4666SKonstantin Aladyshev return; 945cd9a4666SKonstantin Aladyshev } 946cd9a4666SKonstantin Aladyshev 947cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootTypeStr; 948cd9a4666SKonstantin Aladyshev 949cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode@Redfish." 950cd9a4666SKonstantin Aladyshev "AllowableValues"] = {"Legacy", 951cd9a4666SKonstantin Aladyshev "UEFI"}; 952cd9a4666SKonstantin Aladyshev 953cd9a4666SKonstantin Aladyshev auto rfType = dbusToRfBootType(*bootTypeStr); 954cd9a4666SKonstantin Aladyshev if (rfType.empty()) 955cd9a4666SKonstantin Aladyshev { 956cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 957cd9a4666SKonstantin Aladyshev return; 958cd9a4666SKonstantin Aladyshev } 959cd9a4666SKonstantin Aladyshev 960cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 961cd9a4666SKonstantin Aladyshev }, 962*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 963*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 964cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Get", 965cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType"); 966cd9a4666SKonstantin Aladyshev } 967cd9a4666SKonstantin Aladyshev 968cd9a4666SKonstantin Aladyshev /** 969*c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 970491d8ee7SSantosh Puranik * 971491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 972491d8ee7SSantosh Puranik * 973491d8ee7SSantosh Puranik * @return None. 974491d8ee7SSantosh Puranik */ 975*c21865c4SKonstantin Aladyshev 976*c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 977491d8ee7SSantosh Puranik { 978491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 979*c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 980491d8ee7SSantosh Puranik const std::variant<std::string>& bootMode) { 981491d8ee7SSantosh Puranik if (ec) 982491d8ee7SSantosh Puranik { 983491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 984491d8ee7SSantosh Puranik messages::internalError(aResp->res); 985491d8ee7SSantosh Puranik return; 986491d8ee7SSantosh Puranik } 987491d8ee7SSantosh Puranik 988491d8ee7SSantosh Puranik const std::string* bootModeStr = 989491d8ee7SSantosh Puranik std::get_if<std::string>(&bootMode); 990491d8ee7SSantosh Puranik 991491d8ee7SSantosh Puranik if (!bootModeStr) 992491d8ee7SSantosh Puranik { 993491d8ee7SSantosh Puranik messages::internalError(aResp->res); 994491d8ee7SSantosh Puranik return; 995491d8ee7SSantosh Puranik } 996491d8ee7SSantosh Puranik 997491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr; 998491d8ee7SSantosh Puranik 999491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish." 1000491d8ee7SSantosh Puranik "AllowableValues"] = { 1001944ffaf9SJohnathan Mantey "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1002491d8ee7SSantosh Puranik 1003491d8ee7SSantosh Puranik if (*bootModeStr != 1004491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1005491d8ee7SSantosh Puranik { 1006491d8ee7SSantosh Puranik auto rfMode = dbusToRfBootMode(*bootModeStr); 1007491d8ee7SSantosh Puranik if (!rfMode.empty()) 1008491d8ee7SSantosh Puranik { 1009491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1010491d8ee7SSantosh Puranik rfMode; 1011491d8ee7SSantosh Puranik } 1012491d8ee7SSantosh Puranik } 1013491d8ee7SSantosh Puranik }, 1014*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1015*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1016491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Get", 1017491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode"); 1018491d8ee7SSantosh Puranik } 1019491d8ee7SSantosh Puranik 1020491d8ee7SSantosh Puranik /** 1021*c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1022491d8ee7SSantosh Puranik * 1023491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1024491d8ee7SSantosh Puranik * 1025491d8ee7SSantosh Puranik * @return None. 1026491d8ee7SSantosh Puranik */ 1027*c21865c4SKonstantin Aladyshev 1028*c21865c4SKonstantin Aladyshev inline void 1029*c21865c4SKonstantin Aladyshev getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1030491d8ee7SSantosh Puranik { 1031491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1032*c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 1033491d8ee7SSantosh Puranik const std::variant<std::string>& bootSource) { 1034491d8ee7SSantosh Puranik if (ec) 1035491d8ee7SSantosh Puranik { 1036491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1037491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1038491d8ee7SSantosh Puranik return; 1039491d8ee7SSantosh Puranik } 1040491d8ee7SSantosh Puranik 1041491d8ee7SSantosh Puranik const std::string* bootSourceStr = 1042491d8ee7SSantosh Puranik std::get_if<std::string>(&bootSource); 1043491d8ee7SSantosh Puranik 1044491d8ee7SSantosh Puranik if (!bootSourceStr) 1045491d8ee7SSantosh Puranik { 1046491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1047491d8ee7SSantosh Puranik return; 1048491d8ee7SSantosh Puranik } 1049491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr; 1050491d8ee7SSantosh Puranik 1051491d8ee7SSantosh Puranik auto rfSource = dbusToRfBootSource(*bootSourceStr); 1052491d8ee7SSantosh Puranik if (!rfSource.empty()) 1053491d8ee7SSantosh Puranik { 1054491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1055491d8ee7SSantosh Puranik rfSource; 1056491d8ee7SSantosh Puranik } 1057cd9a4666SKonstantin Aladyshev 1058cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1059cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1060*c21865c4SKonstantin Aladyshev getBootOverrideMode(aResp); 1061491d8ee7SSantosh Puranik }, 1062*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1063*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1064491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Get", 1065491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource"); 1066491d8ee7SSantosh Puranik } 1067491d8ee7SSantosh Puranik 1068491d8ee7SSantosh Puranik /** 1069*c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1070*c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1071*c21865c4SKonstantin Aladyshev * state 1072491d8ee7SSantosh Puranik * 1073491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1074491d8ee7SSantosh Puranik * 1075491d8ee7SSantosh Puranik * @return None. 1076491d8ee7SSantosh Puranik */ 1077491d8ee7SSantosh Puranik 1078*c21865c4SKonstantin Aladyshev inline void 1079*c21865c4SKonstantin Aladyshev processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1080*c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1081*c21865c4SKonstantin Aladyshev { 1082*c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1083*c21865c4SKonstantin Aladyshev { 1084*c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; 1085*c21865c4SKonstantin Aladyshev return; 1086*c21865c4SKonstantin Aladyshev } 1087*c21865c4SKonstantin Aladyshev 1088*c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1089*c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 1090491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1091c5d03ff4SJennifer Lee [aResp](const boost::system::error_code ec, 109219bd78d9SPatrick Williams const std::variant<bool>& oneTime) { 1093491d8ee7SSantosh Puranik if (ec) 1094491d8ee7SSantosh Puranik { 1095491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1096*c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1097491d8ee7SSantosh Puranik return; 1098491d8ee7SSantosh Puranik } 1099491d8ee7SSantosh Puranik 1100491d8ee7SSantosh Puranik const bool* oneTimePtr = std::get_if<bool>(&oneTime); 1101491d8ee7SSantosh Puranik 1102491d8ee7SSantosh Puranik if (!oneTimePtr) 1103491d8ee7SSantosh Puranik { 1104491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1105491d8ee7SSantosh Puranik return; 1106491d8ee7SSantosh Puranik } 1107*c21865c4SKonstantin Aladyshev 1108*c21865c4SKonstantin Aladyshev bool oneTimeSetting = *oneTimePtr; 1109*c21865c4SKonstantin Aladyshev 1110*c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1111*c21865c4SKonstantin Aladyshev { 1112*c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1113*c21865c4SKonstantin Aladyshev "Once"; 1114*c21865c4SKonstantin Aladyshev } 1115*c21865c4SKonstantin Aladyshev else 1116*c21865c4SKonstantin Aladyshev { 1117*c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1118*c21865c4SKonstantin Aladyshev "Continuous"; 1119*c21865c4SKonstantin Aladyshev } 1120491d8ee7SSantosh Puranik }, 1121491d8ee7SSantosh Puranik "xyz.openbmc_project.Settings", 1122491d8ee7SSantosh Puranik "/xyz/openbmc_project/control/host0/boot/one_time", 1123491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Get", 1124491d8ee7SSantosh Puranik "xyz.openbmc_project.Object.Enable", "Enabled"); 1125491d8ee7SSantosh Puranik } 1126491d8ee7SSantosh Puranik 1127491d8ee7SSantosh Puranik /** 1128*c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1129*c21865c4SKonstantin Aladyshev * 1130*c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1131*c21865c4SKonstantin Aladyshev * 1132*c21865c4SKonstantin Aladyshev * @return None. 1133*c21865c4SKonstantin Aladyshev */ 1134*c21865c4SKonstantin Aladyshev 1135*c21865c4SKonstantin Aladyshev inline void 1136*c21865c4SKonstantin Aladyshev getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1137*c21865c4SKonstantin Aladyshev { 1138*c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1139*c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec, 1140*c21865c4SKonstantin Aladyshev const std::variant<bool>& bootOverrideEnable) { 1141*c21865c4SKonstantin Aladyshev if (ec) 1142*c21865c4SKonstantin Aladyshev { 1143*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1144*c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1145*c21865c4SKonstantin Aladyshev return; 1146*c21865c4SKonstantin Aladyshev } 1147*c21865c4SKonstantin Aladyshev 1148*c21865c4SKonstantin Aladyshev const bool* bootOverrideEnablePtr = 1149*c21865c4SKonstantin Aladyshev std::get_if<bool>(&bootOverrideEnable); 1150*c21865c4SKonstantin Aladyshev 1151*c21865c4SKonstantin Aladyshev if (!bootOverrideEnablePtr) 1152*c21865c4SKonstantin Aladyshev { 1153*c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1154*c21865c4SKonstantin Aladyshev return; 1155*c21865c4SKonstantin Aladyshev } 1156*c21865c4SKonstantin Aladyshev 1157*c21865c4SKonstantin Aladyshev processBootOverrideEnable(aResp, *bootOverrideEnablePtr); 1158*c21865c4SKonstantin Aladyshev }, 1159*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1160*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1161*c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Get", 1162*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled"); 1163*c21865c4SKonstantin Aladyshev } 1164*c21865c4SKonstantin Aladyshev 1165*c21865c4SKonstantin Aladyshev /** 1166*c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1167*c21865c4SKonstantin Aladyshev * 1168*c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1169*c21865c4SKonstantin Aladyshev * 1170*c21865c4SKonstantin Aladyshev * @return None. 1171*c21865c4SKonstantin Aladyshev */ 1172*c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1173*c21865c4SKonstantin Aladyshev { 1174*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1175*c21865c4SKonstantin Aladyshev 1176*c21865c4SKonstantin Aladyshev getBootOverrideSource(aResp); 1177*c21865c4SKonstantin Aladyshev getBootOverrideType(aResp); 1178*c21865c4SKonstantin Aladyshev getBootOverrideEnable(aResp); 1179*c21865c4SKonstantin Aladyshev } 1180*c21865c4SKonstantin Aladyshev 1181*c21865c4SKonstantin Aladyshev /** 1182c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1183c0557e1aSGunnar Mills * 1184c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1185c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1186c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1187c0557e1aSGunnar Mills * last power operation time. 1188c0557e1aSGunnar Mills * 1189c0557e1aSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 1190c0557e1aSGunnar Mills * 1191c0557e1aSGunnar Mills * @return None. 1192c0557e1aSGunnar Mills */ 11938d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1194c0557e1aSGunnar Mills { 1195c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1196c0557e1aSGunnar Mills 1197c0557e1aSGunnar Mills crow::connections::systemBus->async_method_call( 1198c0557e1aSGunnar Mills [aResp](const boost::system::error_code ec, 1199c0557e1aSGunnar Mills std::variant<uint64_t>& lastResetTime) { 1200c0557e1aSGunnar Mills if (ec) 1201c0557e1aSGunnar Mills { 1202c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1203c0557e1aSGunnar Mills return; 1204c0557e1aSGunnar Mills } 1205c0557e1aSGunnar Mills 1206c0557e1aSGunnar Mills const uint64_t* lastResetTimePtr = 1207c0557e1aSGunnar Mills std::get_if<uint64_t>(&lastResetTime); 1208c0557e1aSGunnar Mills 1209c0557e1aSGunnar Mills if (!lastResetTimePtr) 1210c0557e1aSGunnar Mills { 1211c0557e1aSGunnar Mills messages::internalError(aResp->res); 1212c0557e1aSGunnar Mills return; 1213c0557e1aSGunnar Mills } 1214c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1215c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 1216c0557e1aSGunnar Mills time_t lastResetTimeStamp = 1217c0557e1aSGunnar Mills static_cast<time_t>(*lastResetTimePtr / 1000); 1218c0557e1aSGunnar Mills 1219c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1220c0557e1aSGunnar Mills aResp->res.jsonValue["LastResetTime"] = 1221c0557e1aSGunnar Mills crow::utility::getDateTime(lastResetTimeStamp); 1222c0557e1aSGunnar Mills }, 1223c0557e1aSGunnar Mills "xyz.openbmc_project.State.Chassis", 1224c0557e1aSGunnar Mills "/xyz/openbmc_project/state/chassis0", 1225c0557e1aSGunnar Mills "org.freedesktop.DBus.Properties", "Get", 1226c0557e1aSGunnar Mills "xyz.openbmc_project.State.Chassis", "LastStateChangeTime"); 1227c0557e1aSGunnar Mills } 1228c0557e1aSGunnar Mills 1229c0557e1aSGunnar Mills /** 12306bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12316bd5a8d2SGunnar Mills * 12326bd5a8d2SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 12336bd5a8d2SGunnar Mills * 12346bd5a8d2SGunnar Mills * @return None. 12356bd5a8d2SGunnar Mills */ 12368d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 12376bd5a8d2SGunnar Mills { 12386bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 12396bd5a8d2SGunnar Mills 12406bd5a8d2SGunnar Mills crow::connections::systemBus->async_method_call( 12416bd5a8d2SGunnar Mills [aResp](const boost::system::error_code ec, 12426bd5a8d2SGunnar Mills std::variant<bool>& autoRebootEnabled) { 12436bd5a8d2SGunnar Mills if (ec) 12446bd5a8d2SGunnar Mills { 12456bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 12466bd5a8d2SGunnar Mills return; 12476bd5a8d2SGunnar Mills } 12486bd5a8d2SGunnar Mills 12496bd5a8d2SGunnar Mills const bool* autoRebootEnabledPtr = 12506bd5a8d2SGunnar Mills std::get_if<bool>(&autoRebootEnabled); 12516bd5a8d2SGunnar Mills 12526bd5a8d2SGunnar Mills if (!autoRebootEnabledPtr) 12536bd5a8d2SGunnar Mills { 12546bd5a8d2SGunnar Mills messages::internalError(aResp->res); 12556bd5a8d2SGunnar Mills return; 12566bd5a8d2SGunnar Mills } 12576bd5a8d2SGunnar Mills 12586bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr; 12596bd5a8d2SGunnar Mills if (*autoRebootEnabledPtr == true) 12606bd5a8d2SGunnar Mills { 12616bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12626bd5a8d2SGunnar Mills "RetryAttempts"; 12636bd5a8d2SGunnar Mills // If AutomaticRetry (AutoReboot) is enabled see how many 12646bd5a8d2SGunnar Mills // attempts are left 12656bd5a8d2SGunnar Mills crow::connections::systemBus->async_method_call( 1266cb13a392SEd Tanous [aResp](const boost::system::error_code ec2, 12676bd5a8d2SGunnar Mills std::variant<uint32_t>& autoRebootAttemptsLeft) { 1268cb13a392SEd Tanous if (ec2) 12696bd5a8d2SGunnar Mills { 1270cb13a392SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2; 12716bd5a8d2SGunnar Mills return; 12726bd5a8d2SGunnar Mills } 12736bd5a8d2SGunnar Mills 12746bd5a8d2SGunnar Mills const uint32_t* autoRebootAttemptsLeftPtr = 12756bd5a8d2SGunnar Mills std::get_if<uint32_t>(&autoRebootAttemptsLeft); 12766bd5a8d2SGunnar Mills 12776bd5a8d2SGunnar Mills if (!autoRebootAttemptsLeftPtr) 12786bd5a8d2SGunnar Mills { 12796bd5a8d2SGunnar Mills messages::internalError(aResp->res); 12806bd5a8d2SGunnar Mills return; 12816bd5a8d2SGunnar Mills } 12826bd5a8d2SGunnar Mills 12836bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: " 12846bd5a8d2SGunnar Mills << *autoRebootAttemptsLeftPtr; 12856bd5a8d2SGunnar Mills 12866bd5a8d2SGunnar Mills aResp->res 12876bd5a8d2SGunnar Mills .jsonValue["Boot"] 12886bd5a8d2SGunnar Mills ["RemainingAutomaticRetryAttempts"] = 12896bd5a8d2SGunnar Mills *autoRebootAttemptsLeftPtr; 12906bd5a8d2SGunnar Mills }, 12916bd5a8d2SGunnar Mills "xyz.openbmc_project.State.Host", 12926bd5a8d2SGunnar Mills "/xyz/openbmc_project/state/host0", 12936bd5a8d2SGunnar Mills "org.freedesktop.DBus.Properties", "Get", 12946bd5a8d2SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootAttempts", 12956bd5a8d2SGunnar Mills "AttemptsLeft"); 12966bd5a8d2SGunnar Mills } 12976bd5a8d2SGunnar Mills else 12986bd5a8d2SGunnar Mills { 12996bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 13006bd5a8d2SGunnar Mills "Disabled"; 13016bd5a8d2SGunnar Mills } 13026bd5a8d2SGunnar Mills 13036bd5a8d2SGunnar Mills // Not on D-Bus. Hardcoded here: 13046bd5a8d2SGunnar Mills // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71 13056bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3; 130669f35306SGunnar Mills 130769f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 130869f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 130969f35306SGunnar Mills // RetryAttempts. 131069f35306SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish." 131169f35306SGunnar Mills "AllowableValues"] = {"Disabled", 131269f35306SGunnar Mills "RetryAttempts"}; 13136bd5a8d2SGunnar Mills }, 13146bd5a8d2SGunnar Mills "xyz.openbmc_project.Settings", 13156bd5a8d2SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 13166bd5a8d2SGunnar Mills "org.freedesktop.DBus.Properties", "Get", 13176bd5a8d2SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot"); 13186bd5a8d2SGunnar Mills } 13196bd5a8d2SGunnar Mills 13206bd5a8d2SGunnar Mills /** 1321c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1322c6a620f2SGeorge Liu * 1323c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1324c6a620f2SGeorge Liu * 1325c6a620f2SGeorge Liu * @return None. 1326c6a620f2SGeorge Liu */ 13278d1b46d7Szhanghch05 inline void 13288d1b46d7Szhanghch05 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1329c6a620f2SGeorge Liu { 1330c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1331c6a620f2SGeorge Liu 1332c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1333c6a620f2SGeorge Liu [aResp](const boost::system::error_code ec, 133419bd78d9SPatrick Williams std::variant<std::string>& policy) { 1335c6a620f2SGeorge Liu if (ec) 1336c6a620f2SGeorge Liu { 1337c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1338c6a620f2SGeorge Liu return; 1339c6a620f2SGeorge Liu } 1340c6a620f2SGeorge Liu 1341c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> 1342c6a620f2SGeorge Liu policyMaps = { 1343c6a620f2SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1344c6a620f2SGeorge Liu "AlwaysOn", 1345c6a620f2SGeorge Liu "AlwaysOn"}, 1346c6a620f2SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1347c6a620f2SGeorge Liu "AlwaysOff", 1348c6a620f2SGeorge Liu "AlwaysOff"}, 1349c6a620f2SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 135037ec9072SGunnar Mills "Restore", 1351c6a620f2SGeorge Liu "LastState"}}; 1352c6a620f2SGeorge Liu 1353c6a620f2SGeorge Liu const std::string* policyPtr = std::get_if<std::string>(&policy); 1354c6a620f2SGeorge Liu 1355c6a620f2SGeorge Liu if (!policyPtr) 1356c6a620f2SGeorge Liu { 1357c6a620f2SGeorge Liu messages::internalError(aResp->res); 1358c6a620f2SGeorge Liu return; 1359c6a620f2SGeorge Liu } 1360c6a620f2SGeorge Liu 1361c6a620f2SGeorge Liu auto policyMapsIt = policyMaps.find(*policyPtr); 1362c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1363c6a620f2SGeorge Liu { 1364c6a620f2SGeorge Liu messages::internalError(aResp->res); 1365c6a620f2SGeorge Liu return; 1366c6a620f2SGeorge Liu } 1367c6a620f2SGeorge Liu 1368c6a620f2SGeorge Liu aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second; 1369c6a620f2SGeorge Liu }, 1370c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1371c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1372c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Get", 1373c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", 1374c6a620f2SGeorge Liu "PowerRestorePolicy"); 1375c6a620f2SGeorge Liu } 1376c6a620f2SGeorge Liu 1377c6a620f2SGeorge Liu /** 13781981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13791981771bSAli Ahmed * TPM is required for booting the host. 13801981771bSAli Ahmed * 13811981771bSAli Ahmed * @param[in] aResp Shared pointer for generating response message. 13821981771bSAli Ahmed * 13831981771bSAli Ahmed * @return None. 13841981771bSAli Ahmed */ 13851981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 13861981771bSAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp) 13871981771bSAli Ahmed { 13881981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 13891981771bSAli Ahmed 13901981771bSAli Ahmed crow::connections::systemBus->async_method_call( 13911981771bSAli Ahmed [aResp]( 13921981771bSAli Ahmed const boost::system::error_code ec, 13931981771bSAli Ahmed std::vector<std::pair< 13941981771bSAli Ahmed std::string, 13951981771bSAli Ahmed std::vector<std::pair<std::string, std::vector<std::string>>>>>& 13961981771bSAli Ahmed subtree) { 13971981771bSAli Ahmed if (ec) 13981981771bSAli Ahmed { 13991981771bSAli Ahmed BMCWEB_LOG_DEBUG 14001981771bSAli Ahmed << "DBUS response error on TPM.Policy GetSubTree" << ec; 14011981771bSAli Ahmed // This is an optional D-Bus object so just return if 14021981771bSAli Ahmed // error occurs 14031981771bSAli Ahmed return; 14041981771bSAli Ahmed } 14051981771bSAli Ahmed if (subtree.size() == 0) 14061981771bSAli Ahmed { 14071981771bSAli Ahmed // As noted above, this is an optional interface so just return 14081981771bSAli Ahmed // if there is no instance found 14091981771bSAli Ahmed return; 14101981771bSAli Ahmed } 14111981771bSAli Ahmed 14121981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14131981771bSAli Ahmed if (subtree.size() > 1) 14141981771bSAli Ahmed { 14151981771bSAli Ahmed BMCWEB_LOG_DEBUG 14161981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 14171981771bSAli Ahmed << subtree.size(); 14181981771bSAli Ahmed // Throw an internal Error and return 14191981771bSAli Ahmed messages::internalError(aResp->res); 14201981771bSAli Ahmed return; 14211981771bSAli Ahmed } 14221981771bSAli Ahmed 14231981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14241981771bSAli Ahmed // field 14251981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14261981771bSAli Ahmed { 14271981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 14281981771bSAli Ahmed messages::internalError(aResp->res); 14291981771bSAli Ahmed return; 14301981771bSAli Ahmed } 14311981771bSAli Ahmed 14321981771bSAli Ahmed const std::string& path = subtree[0].first; 14331981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14341981771bSAli Ahmed 14351981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14361981771bSAli Ahmed crow::connections::systemBus->async_method_call( 14371981771bSAli Ahmed [aResp](const boost::system::error_code ec, 14381981771bSAli Ahmed std::variant<bool>& tpmRequired) { 14391981771bSAli Ahmed if (ec) 14401981771bSAli Ahmed { 14411981771bSAli Ahmed BMCWEB_LOG_DEBUG 14421981771bSAli Ahmed << "D-BUS response error on TPM.Policy Get" << ec; 14431981771bSAli Ahmed messages::internalError(aResp->res); 14441981771bSAli Ahmed return; 14451981771bSAli Ahmed } 14461981771bSAli Ahmed 14471981771bSAli Ahmed const bool* tpmRequiredVal = 14481981771bSAli Ahmed std::get_if<bool>(&tpmRequired); 14491981771bSAli Ahmed 14501981771bSAli Ahmed if (!tpmRequiredVal) 14511981771bSAli Ahmed { 14521981771bSAli Ahmed messages::internalError(aResp->res); 14531981771bSAli Ahmed return; 14541981771bSAli Ahmed } 14551981771bSAli Ahmed 14561981771bSAli Ahmed if (*tpmRequiredVal == true) 14571981771bSAli Ahmed { 14581981771bSAli Ahmed aResp->res 14591981771bSAli Ahmed .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14601981771bSAli Ahmed "Required"; 14611981771bSAli Ahmed } 14621981771bSAli Ahmed else 14631981771bSAli Ahmed { 14641981771bSAli Ahmed aResp->res 14651981771bSAli Ahmed .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14661981771bSAli Ahmed "Disabled"; 14671981771bSAli Ahmed } 14681981771bSAli Ahmed }, 14691981771bSAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Get", 14701981771bSAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable"); 14711981771bSAli Ahmed }, 14721981771bSAli Ahmed "xyz.openbmc_project.ObjectMapper", 14731981771bSAli Ahmed "/xyz/openbmc_project/object_mapper", 14741981771bSAli Ahmed "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 14751981771bSAli Ahmed std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"}); 14761981771bSAli Ahmed } 14771981771bSAli Ahmed 14781981771bSAli Ahmed /** 1479491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1480491d8ee7SSantosh Puranik * 1481491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1482cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1483cd9a4666SKonstantin Aladyshev * @return Integer error code. 1484cd9a4666SKonstantin Aladyshev */ 1485cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1486cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1487cd9a4666SKonstantin Aladyshev { 1488*c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1489cd9a4666SKonstantin Aladyshev 1490*c21865c4SKonstantin Aladyshev if (!bootType) 1491cd9a4666SKonstantin Aladyshev { 1492*c21865c4SKonstantin Aladyshev return; 1493*c21865c4SKonstantin Aladyshev } 1494*c21865c4SKonstantin Aladyshev 1495cd9a4666SKonstantin Aladyshev // Source target specified 1496cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1497cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1498cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1499cd9a4666SKonstantin Aladyshev { 1500cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1501cd9a4666SKonstantin Aladyshev } 1502cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1503cd9a4666SKonstantin Aladyshev { 1504cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1505cd9a4666SKonstantin Aladyshev } 1506cd9a4666SKonstantin Aladyshev else 1507cd9a4666SKonstantin Aladyshev { 1508cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1509cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1510cd9a4666SKonstantin Aladyshev << *bootType; 1511cd9a4666SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootType, 1512cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1513cd9a4666SKonstantin Aladyshev return; 1514cd9a4666SKonstantin Aladyshev } 1515cd9a4666SKonstantin Aladyshev 1516cd9a4666SKonstantin Aladyshev // Act on validated parameters 1517cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1518cd9a4666SKonstantin Aladyshev 1519cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1520*c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1521cd9a4666SKonstantin Aladyshev if (ec) 1522cd9a4666SKonstantin Aladyshev { 1523cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1524cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1525cd9a4666SKonstantin Aladyshev { 1526cd9a4666SKonstantin Aladyshev messages::resourceNotFound(aResp->res, "Set", "BootType"); 1527cd9a4666SKonstantin Aladyshev return; 1528cd9a4666SKonstantin Aladyshev } 1529cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 1530cd9a4666SKonstantin Aladyshev return; 1531cd9a4666SKonstantin Aladyshev } 1532cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1533cd9a4666SKonstantin Aladyshev }, 1534*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1535*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1536cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1537cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1538cd9a4666SKonstantin Aladyshev std::variant<std::string>(bootTypeStr)); 1539cd9a4666SKonstantin Aladyshev } 1540cd9a4666SKonstantin Aladyshev 1541cd9a4666SKonstantin Aladyshev /** 1542cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1543cd9a4666SKonstantin Aladyshev * 1544cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1545*c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1546*c21865c4SKonstantin Aladyshev * @return Integer error code. 1547*c21865c4SKonstantin Aladyshev */ 1548*c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1549*c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1550*c21865c4SKonstantin Aladyshev { 1551*c21865c4SKonstantin Aladyshev if (!bootEnable) 1552*c21865c4SKonstantin Aladyshev { 1553*c21865c4SKonstantin Aladyshev return; 1554*c21865c4SKonstantin Aladyshev } 1555*c21865c4SKonstantin Aladyshev // Source target specified 1556*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1557*c21865c4SKonstantin Aladyshev 1558*c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1559*c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1560*c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1561*c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1562*c21865c4SKonstantin Aladyshev { 1563*c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1564*c21865c4SKonstantin Aladyshev } 1565*c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1566*c21865c4SKonstantin Aladyshev { 1567*c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1568*c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1569*c21865c4SKonstantin Aladyshev } 1570*c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1571*c21865c4SKonstantin Aladyshev { 1572*c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1573*c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1574*c21865c4SKonstantin Aladyshev } 1575*c21865c4SKonstantin Aladyshev else 1576*c21865c4SKonstantin Aladyshev { 1577*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1578*c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled: " 1579*c21865c4SKonstantin Aladyshev << *bootEnable; 1580*c21865c4SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootEnable, 1581*c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1582*c21865c4SKonstantin Aladyshev return; 1583*c21865c4SKonstantin Aladyshev } 1584*c21865c4SKonstantin Aladyshev 1585*c21865c4SKonstantin Aladyshev // Act on validated parameters 1586*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1587*c21865c4SKonstantin Aladyshev 1588*c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1589*c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1590*c21865c4SKonstantin Aladyshev if (ec) 1591*c21865c4SKonstantin Aladyshev { 1592*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1593*c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1594*c21865c4SKonstantin Aladyshev return; 1595*c21865c4SKonstantin Aladyshev } 1596*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1597*c21865c4SKonstantin Aladyshev }, 1598*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1599*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1600*c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1601*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1602*c21865c4SKonstantin Aladyshev std::variant<bool>(bootOverrideEnable)); 1603*c21865c4SKonstantin Aladyshev 1604*c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1605*c21865c4SKonstantin Aladyshev { 1606*c21865c4SKonstantin Aladyshev return; 1607*c21865c4SKonstantin Aladyshev } 1608*c21865c4SKonstantin Aladyshev 1609*c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1610*c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1611*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1612*c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1613*c21865c4SKonstantin Aladyshev 1614*c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1615*c21865c4SKonstantin Aladyshev [aResp](const boost::system::error_code ec) { 1616*c21865c4SKonstantin Aladyshev if (ec) 1617*c21865c4SKonstantin Aladyshev { 1618*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1619*c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1620*c21865c4SKonstantin Aladyshev return; 1621*c21865c4SKonstantin Aladyshev } 1622*c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1623*c21865c4SKonstantin Aladyshev }, 1624*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1625*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1626*c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1627*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1628*c21865c4SKonstantin Aladyshev std::variant<bool>(!bootOverridePersistent)); 1629*c21865c4SKonstantin Aladyshev } 1630*c21865c4SKonstantin Aladyshev 1631*c21865c4SKonstantin Aladyshev /** 1632*c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1633*c21865c4SKonstantin Aladyshev * 1634*c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1635491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1636491d8ee7SSantosh Puranik * 1637265c1602SJohnathan Mantey * @return Integer error code. 1638491d8ee7SSantosh Puranik */ 1639cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1640cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1641491d8ee7SSantosh Puranik { 1642*c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1643*c21865c4SKonstantin Aladyshev std::string bootModeStr; 1644944ffaf9SJohnathan Mantey 1645*c21865c4SKonstantin Aladyshev if (!bootSource) 1646491d8ee7SSantosh Puranik { 1647*c21865c4SKonstantin Aladyshev return; 1648*c21865c4SKonstantin Aladyshev } 1649*c21865c4SKonstantin Aladyshev 1650491d8ee7SSantosh Puranik // Source target specified 1651491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1652491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1653*c21865c4SKonstantin Aladyshev if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr)) 1654491d8ee7SSantosh Puranik { 1655944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1656944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1657491d8ee7SSantosh Puranik << *bootSource; 1658491d8ee7SSantosh Puranik messages::propertyValueNotInList(aResp->res, *bootSource, 1659491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1660491d8ee7SSantosh Puranik return; 1661491d8ee7SSantosh Puranik } 1662491d8ee7SSantosh Puranik 1663944ffaf9SJohnathan Mantey // Act on validated parameters 1664944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1665944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1666944ffaf9SJohnathan Mantey 1667491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1668491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1669491d8ee7SSantosh Puranik if (ec) 1670491d8ee7SSantosh Puranik { 1671491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1672491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1673491d8ee7SSantosh Puranik return; 1674491d8ee7SSantosh Puranik } 1675491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1676491d8ee7SSantosh Puranik }, 1677*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1678*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1679491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1680491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1681491d8ee7SSantosh Puranik std::variant<std::string>(bootSourceStr)); 1682944ffaf9SJohnathan Mantey 1683491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1684491d8ee7SSantosh Puranik [aResp](const boost::system::error_code ec) { 1685491d8ee7SSantosh Puranik if (ec) 1686491d8ee7SSantosh Puranik { 1687491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1688491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1689491d8ee7SSantosh Puranik return; 1690491d8ee7SSantosh Puranik } 1691491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1692491d8ee7SSantosh Puranik }, 1693*c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1694*c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1695491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1696491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1697491d8ee7SSantosh Puranik std::variant<std::string>(bootModeStr)); 1698cd9a4666SKonstantin Aladyshev } 1699944ffaf9SJohnathan Mantey 1700cd9a4666SKonstantin Aladyshev /** 1701*c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1702491d8ee7SSantosh Puranik * 1703491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1704491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1705cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1706491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1707491d8ee7SSantosh Puranik * 1708265c1602SJohnathan Mantey * @return Integer error code. 1709491d8ee7SSantosh Puranik */ 1710*c21865c4SKonstantin Aladyshev 1711*c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1712*c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1713*c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1714*c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1715491d8ee7SSantosh Puranik { 1716491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1717491d8ee7SSantosh Puranik 1718*c21865c4SKonstantin Aladyshev setBootModeOrSource(aResp, bootSource); 1719*c21865c4SKonstantin Aladyshev setBootType(aResp, bootType); 1720*c21865c4SKonstantin Aladyshev setBootEnable(aResp, bootEnable); 1721491d8ee7SSantosh Puranik } 1722491d8ee7SSantosh Puranik 1723c6a620f2SGeorge Liu /** 172498e386ecSGunnar Mills * @brief Sets AssetTag 172598e386ecSGunnar Mills * 172698e386ecSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 172798e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 172898e386ecSGunnar Mills * 172998e386ecSGunnar Mills * @return None. 173098e386ecSGunnar Mills */ 17318d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 173298e386ecSGunnar Mills const std::string& assetTag) 173398e386ecSGunnar Mills { 173498e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 173598e386ecSGunnar Mills [aResp, assetTag]( 173698e386ecSGunnar Mills const boost::system::error_code ec, 173798e386ecSGunnar Mills const std::vector<std::pair< 173898e386ecSGunnar Mills std::string, 173998e386ecSGunnar Mills std::vector<std::pair<std::string, std::vector<std::string>>>>>& 174098e386ecSGunnar Mills subtree) { 174198e386ecSGunnar Mills if (ec) 174298e386ecSGunnar Mills { 174398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 174498e386ecSGunnar Mills messages::internalError(aResp->res); 174598e386ecSGunnar Mills return; 174698e386ecSGunnar Mills } 174798e386ecSGunnar Mills if (subtree.size() == 0) 174898e386ecSGunnar Mills { 174998e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 175098e386ecSGunnar Mills messages::internalError(aResp->res); 175198e386ecSGunnar Mills return; 175298e386ecSGunnar Mills } 175398e386ecSGunnar Mills // Assume only 1 system D-Bus object 175498e386ecSGunnar Mills // Throw an error if there is more than 1 175598e386ecSGunnar Mills if (subtree.size() > 1) 175698e386ecSGunnar Mills { 175798e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 175898e386ecSGunnar Mills messages::internalError(aResp->res); 175998e386ecSGunnar Mills return; 176098e386ecSGunnar Mills } 176198e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 176298e386ecSGunnar Mills { 176398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 176498e386ecSGunnar Mills messages::internalError(aResp->res); 176598e386ecSGunnar Mills return; 176698e386ecSGunnar Mills } 176798e386ecSGunnar Mills 176898e386ecSGunnar Mills const std::string& path = subtree[0].first; 176998e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 177098e386ecSGunnar Mills 177198e386ecSGunnar Mills if (service.empty()) 177298e386ecSGunnar Mills { 177398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 177498e386ecSGunnar Mills messages::internalError(aResp->res); 177598e386ecSGunnar Mills return; 177698e386ecSGunnar Mills } 177798e386ecSGunnar Mills 177898e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 177998e386ecSGunnar Mills [aResp](const boost::system::error_code ec2) { 178098e386ecSGunnar Mills if (ec2) 178198e386ecSGunnar Mills { 178298e386ecSGunnar Mills BMCWEB_LOG_DEBUG 178398e386ecSGunnar Mills << "D-Bus response error on AssetTag Set " << ec2; 178498e386ecSGunnar Mills messages::internalError(aResp->res); 178598e386ecSGunnar Mills return; 178698e386ecSGunnar Mills } 178798e386ecSGunnar Mills }, 178898e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 178998e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 179098e386ecSGunnar Mills std::variant<std::string>(assetTag)); 179198e386ecSGunnar Mills }, 179298e386ecSGunnar Mills "xyz.openbmc_project.ObjectMapper", 179398e386ecSGunnar Mills "/xyz/openbmc_project/object_mapper", 179498e386ecSGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 179598e386ecSGunnar Mills "/xyz/openbmc_project/inventory", int32_t(0), 179698e386ecSGunnar Mills std::array<const char*, 1>{ 179798e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Item.System"}); 179898e386ecSGunnar Mills } 179998e386ecSGunnar Mills 180098e386ecSGunnar Mills /** 180169f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 180269f35306SGunnar Mills * 180369f35306SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 180469f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 180569f35306SGunnar Mills * 180669f35306SGunnar Mills * @return None. 180769f35306SGunnar Mills */ 18088d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1809f23b7296SEd Tanous const std::string& automaticRetryConfig) 181069f35306SGunnar Mills { 181169f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 181269f35306SGunnar Mills 181369f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 181469f35306SGunnar Mills bool autoRebootEnabled; 181569f35306SGunnar Mills 181669f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 181769f35306SGunnar Mills { 181869f35306SGunnar Mills autoRebootEnabled = false; 181969f35306SGunnar Mills } 182069f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 182169f35306SGunnar Mills { 182269f35306SGunnar Mills autoRebootEnabled = true; 182369f35306SGunnar Mills } 182469f35306SGunnar Mills else 182569f35306SGunnar Mills { 182669f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property value for " 182769f35306SGunnar Mills "AutomaticRetryConfig: " 182869f35306SGunnar Mills << automaticRetryConfig; 182969f35306SGunnar Mills messages::propertyValueNotInList(aResp->res, automaticRetryConfig, 183069f35306SGunnar Mills "AutomaticRetryConfig"); 183169f35306SGunnar Mills return; 183269f35306SGunnar Mills } 183369f35306SGunnar Mills 183469f35306SGunnar Mills crow::connections::systemBus->async_method_call( 183569f35306SGunnar Mills [aResp](const boost::system::error_code ec) { 183669f35306SGunnar Mills if (ec) 183769f35306SGunnar Mills { 183869f35306SGunnar Mills messages::internalError(aResp->res); 183969f35306SGunnar Mills return; 184069f35306SGunnar Mills } 184169f35306SGunnar Mills }, 184269f35306SGunnar Mills "xyz.openbmc_project.Settings", 184369f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 184469f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 184569f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 184669f35306SGunnar Mills std::variant<bool>(autoRebootEnabled)); 184769f35306SGunnar Mills } 184869f35306SGunnar Mills 184969f35306SGunnar Mills /** 1850c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1851c6a620f2SGeorge Liu * 1852c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1853c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1854c6a620f2SGeorge Liu * 1855c6a620f2SGeorge Liu * @return None. 1856c6a620f2SGeorge Liu */ 18578d1b46d7Szhanghch05 inline void 18588d1b46d7Szhanghch05 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 18594e69c904SGunnar Mills const std::string& policy) 1860c6a620f2SGeorge Liu { 1861c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1862c6a620f2SGeorge Liu 1863c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 1864c6a620f2SGeorge Liu {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1865c6a620f2SGeorge Liu "AlwaysOn"}, 1866c6a620f2SGeorge Liu {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 1867c6a620f2SGeorge Liu "AlwaysOff"}, 1868c6a620f2SGeorge Liu {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy." 186937ec9072SGunnar Mills "Restore"}}; 1870c6a620f2SGeorge Liu 1871c6a620f2SGeorge Liu std::string powerRestorPolicy; 1872c6a620f2SGeorge Liu 18734e69c904SGunnar Mills auto policyMapsIt = policyMaps.find(policy); 1874c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1875c6a620f2SGeorge Liu { 18764e69c904SGunnar Mills messages::propertyValueNotInList(aResp->res, policy, 18774e69c904SGunnar Mills "PowerRestorePolicy"); 1878c6a620f2SGeorge Liu return; 1879c6a620f2SGeorge Liu } 1880c6a620f2SGeorge Liu 1881c6a620f2SGeorge Liu powerRestorPolicy = policyMapsIt->second; 1882c6a620f2SGeorge Liu 1883c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1884c6a620f2SGeorge Liu [aResp](const boost::system::error_code ec) { 1885c6a620f2SGeorge Liu if (ec) 1886c6a620f2SGeorge Liu { 1887c6a620f2SGeorge Liu messages::internalError(aResp->res); 1888c6a620f2SGeorge Liu return; 1889c6a620f2SGeorge Liu } 1890c6a620f2SGeorge Liu }, 1891c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1892c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1893c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1894c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1895c6a620f2SGeorge Liu std::variant<std::string>(powerRestorPolicy)); 1896c6a620f2SGeorge Liu } 1897c6a620f2SGeorge Liu 1898a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 1899a6349918SAppaRao Puli /** 1900a6349918SAppaRao Puli * @brief Retrieves provisioning status 1901a6349918SAppaRao Puli * 1902a6349918SAppaRao Puli * @param[in] aResp Shared pointer for completing asynchronous calls. 1903a6349918SAppaRao Puli * 1904a6349918SAppaRao Puli * @return None. 1905a6349918SAppaRao Puli */ 19068d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp) 1907a6349918SAppaRao Puli { 1908a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 1909a6349918SAppaRao Puli crow::connections::systemBus->async_method_call( 1910a6349918SAppaRao Puli [aResp](const boost::system::error_code ec, 19111214b7e7SGunnar Mills const std::vector<std::pair<std::string, VariantType>>& 19121214b7e7SGunnar Mills propertiesList) { 1913b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1914b99fb1a9SAppaRao Puli aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 191550626f4fSJames Feist aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 191650626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 191750626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 191850626f4fSJames Feist 1919a6349918SAppaRao Puli if (ec) 1920a6349918SAppaRao Puli { 1921a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1922b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1923b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1924a6349918SAppaRao Puli return; 1925a6349918SAppaRao Puli } 1926a6349918SAppaRao Puli 1927a6349918SAppaRao Puli const bool* provState = nullptr; 1928a6349918SAppaRao Puli const bool* lockState = nullptr; 1929a6349918SAppaRao Puli for (const std::pair<std::string, VariantType>& property : 1930a6349918SAppaRao Puli propertiesList) 1931a6349918SAppaRao Puli { 1932a6349918SAppaRao Puli if (property.first == "UfmProvisioned") 1933a6349918SAppaRao Puli { 1934a6349918SAppaRao Puli provState = std::get_if<bool>(&property.second); 1935a6349918SAppaRao Puli } 1936a6349918SAppaRao Puli else if (property.first == "UfmLocked") 1937a6349918SAppaRao Puli { 1938a6349918SAppaRao Puli lockState = std::get_if<bool>(&property.second); 1939a6349918SAppaRao Puli } 1940a6349918SAppaRao Puli } 1941a6349918SAppaRao Puli 1942a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 1943a6349918SAppaRao Puli { 1944a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 1945a6349918SAppaRao Puli messages::internalError(aResp->res); 1946a6349918SAppaRao Puli return; 1947a6349918SAppaRao Puli } 1948a6349918SAppaRao Puli 1949a6349918SAppaRao Puli if (*provState == true) 1950a6349918SAppaRao Puli { 1951a6349918SAppaRao Puli if (*lockState == true) 1952a6349918SAppaRao Puli { 1953a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 1954a6349918SAppaRao Puli } 1955a6349918SAppaRao Puli else 1956a6349918SAppaRao Puli { 1957a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 1958a6349918SAppaRao Puli } 1959a6349918SAppaRao Puli } 1960a6349918SAppaRao Puli else 1961a6349918SAppaRao Puli { 1962a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1963a6349918SAppaRao Puli } 1964a6349918SAppaRao Puli }, 1965a6349918SAppaRao Puli "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr", 1966a6349918SAppaRao Puli "org.freedesktop.DBus.Properties", "GetAll", 1967a6349918SAppaRao Puli "xyz.openbmc_project.PFR.Attributes"); 1968a6349918SAppaRao Puli } 1969a6349918SAppaRao Puli #endif 1970a6349918SAppaRao Puli 1971491d8ee7SSantosh Puranik /** 19723a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 19733a2d0424SChris Cain * 19743a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 19753a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 19763a2d0424SChris Cain * 19773a2d0424SChris Cain * @return None. 19783a2d0424SChris Cain */ 19793a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 19803a2d0424SChris Cain const std::string& modeValue) 19813a2d0424SChris Cain { 19823a2d0424SChris Cain std::string modeString; 19833a2d0424SChris Cain 19843a2d0424SChris Cain if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 19853a2d0424SChris Cain "PowerMode.Static") 19863a2d0424SChris Cain { 19873a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "Static"; 19883a2d0424SChris Cain } 19893a2d0424SChris Cain else if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 19903a2d0424SChris Cain "PowerMode.MaximumPerformance") 19913a2d0424SChris Cain { 19923a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 19933a2d0424SChris Cain } 19943a2d0424SChris Cain else if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 19953a2d0424SChris Cain "PowerMode.PowerSaving") 19963a2d0424SChris Cain { 19973a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "PowerSaving"; 19983a2d0424SChris Cain } 19993a2d0424SChris Cain else if (modeValue == "xyz.openbmc_project.Control.Power.Mode." 20003a2d0424SChris Cain "PowerMode.OEM") 20013a2d0424SChris Cain { 20023a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "OEM"; 20033a2d0424SChris Cain } 20043a2d0424SChris Cain else 20053a2d0424SChris Cain { 20063a2d0424SChris Cain // Any other values would be invalid 20073a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 20083a2d0424SChris Cain messages::internalError(aResp->res); 20093a2d0424SChris Cain } 20103a2d0424SChris Cain } 20113a2d0424SChris Cain 20123a2d0424SChris Cain /** 20133a2d0424SChris Cain * @brief Retrieves system power mode 20143a2d0424SChris Cain * 20153a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20163a2d0424SChris Cain * 20173a2d0424SChris Cain * @return None. 20183a2d0424SChris Cain */ 20193a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 20203a2d0424SChris Cain { 20213a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 20223a2d0424SChris Cain 20233a2d0424SChris Cain // Get Power Mode object path: 20243a2d0424SChris Cain crow::connections::systemBus->async_method_call( 20253a2d0424SChris Cain [aResp]( 20263a2d0424SChris Cain const boost::system::error_code ec, 20273a2d0424SChris Cain const std::vector<std::pair< 20283a2d0424SChris Cain std::string, 20293a2d0424SChris Cain std::vector<std::pair<std::string, std::vector<std::string>>>>>& 20303a2d0424SChris Cain subtree) { 20313a2d0424SChris Cain if (ec) 20323a2d0424SChris Cain { 20333a2d0424SChris Cain BMCWEB_LOG_DEBUG 20343a2d0424SChris Cain << "DBUS response error on Power.Mode GetSubTree " << ec; 20353a2d0424SChris Cain // This is an optional D-Bus object so just return if 20363a2d0424SChris Cain // error occurs 20373a2d0424SChris Cain return; 20383a2d0424SChris Cain } 20393a2d0424SChris Cain if (subtree.empty()) 20403a2d0424SChris Cain { 20413a2d0424SChris Cain // As noted above, this is an optional interface so just return 20423a2d0424SChris Cain // if there is no instance found 20433a2d0424SChris Cain return; 20443a2d0424SChris Cain } 20453a2d0424SChris Cain if (subtree.size() > 1) 20463a2d0424SChris Cain { 20473a2d0424SChris Cain // More then one PowerMode object is not supported and is an 20483a2d0424SChris Cain // error 20493a2d0424SChris Cain BMCWEB_LOG_DEBUG 20503a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 20513a2d0424SChris Cain << subtree.size(); 20523a2d0424SChris Cain messages::internalError(aResp->res); 20533a2d0424SChris Cain return; 20543a2d0424SChris Cain } 20553a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 20563a2d0424SChris Cain { 20573a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 20583a2d0424SChris Cain messages::internalError(aResp->res); 20593a2d0424SChris Cain return; 20603a2d0424SChris Cain } 20613a2d0424SChris Cain const std::string& path = subtree[0].first; 20623a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 20633a2d0424SChris Cain if (service.empty()) 20643a2d0424SChris Cain { 20653a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 20663a2d0424SChris Cain messages::internalError(aResp->res); 20673a2d0424SChris Cain return; 20683a2d0424SChris Cain } 20693a2d0424SChris Cain // Valid Power Mode object found, now read the current value 20703a2d0424SChris Cain crow::connections::systemBus->async_method_call( 20713a2d0424SChris Cain [aResp](const boost::system::error_code ec, 20723a2d0424SChris Cain const std::variant<std::string>& pmode) { 20733a2d0424SChris Cain if (ec) 20743a2d0424SChris Cain { 20753a2d0424SChris Cain BMCWEB_LOG_DEBUG 20763a2d0424SChris Cain << "DBUS response error on PowerMode Get: " << ec; 20773a2d0424SChris Cain messages::internalError(aResp->res); 20783a2d0424SChris Cain return; 20793a2d0424SChris Cain } 20803a2d0424SChris Cain 20813a2d0424SChris Cain const std::string* s = std::get_if<std::string>(&pmode); 20823a2d0424SChris Cain if (s == nullptr) 20833a2d0424SChris Cain { 20843a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Unable to get PowerMode value"; 20853a2d0424SChris Cain messages::internalError(aResp->res); 20863a2d0424SChris Cain return; 20873a2d0424SChris Cain } 20883a2d0424SChris Cain 20893a2d0424SChris Cain aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = 20903a2d0424SChris Cain {"Static", "MaximumPerformance", "PowerSaving"}; 20913a2d0424SChris Cain 20923a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Current power mode: " << *s; 20933a2d0424SChris Cain translatePowerMode(aResp, *s); 20943a2d0424SChris Cain }, 20953a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Get", 20963a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode"); 20973a2d0424SChris Cain }, 20983a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", 20993a2d0424SChris Cain "/xyz/openbmc_project/object_mapper", 21003a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 21013a2d0424SChris Cain std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"}); 21023a2d0424SChris Cain } 21033a2d0424SChris Cain 21043a2d0424SChris Cain /** 21053a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21063a2d0424SChris Cain * name associated with that string 21073a2d0424SChris Cain * 21083a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21093a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 21103a2d0424SChris Cain * 21113a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 21123a2d0424SChris Cain */ 21133a2d0424SChris Cain inline std::string 21143a2d0424SChris Cain validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21153a2d0424SChris Cain const std::string& modeString) 21163a2d0424SChris Cain { 21173a2d0424SChris Cain std::string mode; 21183a2d0424SChris Cain 21193a2d0424SChris Cain if (modeString == "Static") 21203a2d0424SChris Cain { 21213a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 21223a2d0424SChris Cain } 21233a2d0424SChris Cain else if (modeString == "MaximumPerformance") 21243a2d0424SChris Cain { 21253a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode." 21263a2d0424SChris Cain "MaximumPerformance"; 21273a2d0424SChris Cain } 21283a2d0424SChris Cain else if (modeString == "PowerSaving") 21293a2d0424SChris Cain { 21303a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 21313a2d0424SChris Cain } 21323a2d0424SChris Cain else 21333a2d0424SChris Cain { 21343a2d0424SChris Cain messages::propertyValueNotInList(aResp->res, modeString, "PowerMode"); 21353a2d0424SChris Cain } 21363a2d0424SChris Cain return mode; 21373a2d0424SChris Cain } 21383a2d0424SChris Cain 21393a2d0424SChris Cain /** 21403a2d0424SChris Cain * @brief Sets system power mode. 21413a2d0424SChris Cain * 21423a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21433a2d0424SChris Cain * @param[in] pmode System power mode from request. 21443a2d0424SChris Cain * 21453a2d0424SChris Cain * @return None. 21463a2d0424SChris Cain */ 21473a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21483a2d0424SChris Cain const std::string& pmode) 21493a2d0424SChris Cain { 21503a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 21513a2d0424SChris Cain 21523a2d0424SChris Cain std::string powerMode = validatePowerMode(aResp, pmode); 21533a2d0424SChris Cain if (powerMode.empty()) 21543a2d0424SChris Cain { 21553a2d0424SChris Cain return; 21563a2d0424SChris Cain } 21573a2d0424SChris Cain 21583a2d0424SChris Cain // Get Power Mode object path: 21593a2d0424SChris Cain crow::connections::systemBus->async_method_call( 21603a2d0424SChris Cain [aResp, powerMode]( 21613a2d0424SChris Cain const boost::system::error_code ec, 21623a2d0424SChris Cain const std::vector<std::pair< 21633a2d0424SChris Cain std::string, 21643a2d0424SChris Cain std::vector<std::pair<std::string, std::vector<std::string>>>>>& 21653a2d0424SChris Cain subtree) { 21663a2d0424SChris Cain if (ec) 21673a2d0424SChris Cain { 21683a2d0424SChris Cain BMCWEB_LOG_DEBUG 21693a2d0424SChris Cain << "DBUS response error on Power.Mode GetSubTree " << ec; 21703a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 21713a2d0424SChris Cain messages::internalError(aResp->res); 21723a2d0424SChris Cain return; 21733a2d0424SChris Cain } 21743a2d0424SChris Cain if (subtree.empty()) 21753a2d0424SChris Cain { 21763a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 21773a2d0424SChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 21783a2d0424SChris Cain "PowerMode"); 21793a2d0424SChris Cain return; 21803a2d0424SChris Cain } 21813a2d0424SChris Cain if (subtree.size() > 1) 21823a2d0424SChris Cain { 21833a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21843a2d0424SChris Cain // error 21853a2d0424SChris Cain BMCWEB_LOG_DEBUG 21863a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 21873a2d0424SChris Cain << subtree.size(); 21883a2d0424SChris Cain messages::internalError(aResp->res); 21893a2d0424SChris Cain return; 21903a2d0424SChris Cain } 21913a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21923a2d0424SChris Cain { 21933a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 21943a2d0424SChris Cain messages::internalError(aResp->res); 21953a2d0424SChris Cain return; 21963a2d0424SChris Cain } 21973a2d0424SChris Cain const std::string& path = subtree[0].first; 21983a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21993a2d0424SChris Cain if (service.empty()) 22003a2d0424SChris Cain { 22013a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 22023a2d0424SChris Cain messages::internalError(aResp->res); 22033a2d0424SChris Cain return; 22043a2d0424SChris Cain } 22053a2d0424SChris Cain 22063a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 22073a2d0424SChris Cain << path; 22083a2d0424SChris Cain 22093a2d0424SChris Cain // Set the Power Mode property 22103a2d0424SChris Cain crow::connections::systemBus->async_method_call( 22113a2d0424SChris Cain [aResp](const boost::system::error_code ec) { 22123a2d0424SChris Cain if (ec) 22133a2d0424SChris Cain { 22143a2d0424SChris Cain messages::internalError(aResp->res); 22153a2d0424SChris Cain return; 22163a2d0424SChris Cain } 22173a2d0424SChris Cain }, 22183a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 22193a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 22203a2d0424SChris Cain std::variant<std::string>(powerMode)); 22213a2d0424SChris Cain }, 22223a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", 22233a2d0424SChris Cain "/xyz/openbmc_project/object_mapper", 22243a2d0424SChris Cain "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0), 22253a2d0424SChris Cain std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"}); 22263a2d0424SChris Cain } 22273a2d0424SChris Cain 22283a2d0424SChris Cain /** 222951709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 223051709ffdSYong Li * 223151709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 223251709ffdSYong Li * 223351709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 223451709ffdSYong Li * translation cannot be done, returns an empty string. 223551709ffdSYong Li */ 223623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 223751709ffdSYong Li { 223851709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 223951709ffdSYong Li { 224051709ffdSYong Li return "None"; 224151709ffdSYong Li } 22423174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 224351709ffdSYong Li { 224451709ffdSYong Li return "ResetSystem"; 224551709ffdSYong Li } 22463174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 224751709ffdSYong Li { 224851709ffdSYong Li return "PowerDown"; 224951709ffdSYong Li } 22503174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 225151709ffdSYong Li { 225251709ffdSYong Li return "PowerCycle"; 225351709ffdSYong Li } 225451709ffdSYong Li 225551709ffdSYong Li return ""; 225651709ffdSYong Li } 225751709ffdSYong Li 225851709ffdSYong Li /** 2259c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2260c45f0082SYong Li * 2261c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2262c45f0082SYong Li * 2263c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2264c45f0082SYong Li *If translation cannot be done, returns an empty string. 2265c45f0082SYong Li */ 2266c45f0082SYong Li 226723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2268c45f0082SYong Li { 2269c45f0082SYong Li if (rfAction == "None") 2270c45f0082SYong Li { 2271c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2272c45f0082SYong Li } 22733174e4dfSEd Tanous if (rfAction == "PowerCycle") 2274c45f0082SYong Li { 2275c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2276c45f0082SYong Li } 22773174e4dfSEd Tanous if (rfAction == "PowerDown") 2278c45f0082SYong Li { 2279c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2280c45f0082SYong Li } 22813174e4dfSEd Tanous if (rfAction == "ResetSystem") 2282c45f0082SYong Li { 2283c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2284c45f0082SYong Li } 2285c45f0082SYong Li 2286c45f0082SYong Li return ""; 2287c45f0082SYong Li } 2288c45f0082SYong Li 2289c45f0082SYong Li /** 229051709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 229151709ffdSYong Li * 229251709ffdSYong Li * @param[in] aResp Shared pointer for completing asynchronous calls. 229351709ffdSYong Li * 229451709ffdSYong Li * @return None. 229551709ffdSYong Li */ 22968d1b46d7Szhanghch05 inline void 22978d1b46d7Szhanghch05 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 229851709ffdSYong Li { 229951709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 230051709ffdSYong Li crow::connections::systemBus->async_method_call( 230151709ffdSYong Li [aResp](const boost::system::error_code ec, 230251709ffdSYong Li PropertiesType& properties) { 230351709ffdSYong Li if (ec) 230451709ffdSYong Li { 230551709ffdSYong Li // watchdog service is stopped 230651709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 230751709ffdSYong Li return; 230851709ffdSYong Li } 230951709ffdSYong Li 231051709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 231151709ffdSYong Li 231251709ffdSYong Li nlohmann::json& hostWatchdogTimer = 231351709ffdSYong Li aResp->res.jsonValue["HostWatchdogTimer"]; 231451709ffdSYong Li 231551709ffdSYong Li // watchdog service is running/enabled 231651709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 231751709ffdSYong Li 231851709ffdSYong Li for (const auto& property : properties) 231951709ffdSYong Li { 232051709ffdSYong Li BMCWEB_LOG_DEBUG << "prop=" << property.first; 232151709ffdSYong Li if (property.first == "Enabled") 232251709ffdSYong Li { 232351709ffdSYong Li const bool* state = std::get_if<bool>(&property.second); 232451709ffdSYong Li 232551709ffdSYong Li if (!state) 232651709ffdSYong Li { 232751709ffdSYong Li messages::internalError(aResp->res); 2328601af5edSChicago Duan return; 232951709ffdSYong Li } 233051709ffdSYong Li 233151709ffdSYong Li hostWatchdogTimer["FunctionEnabled"] = *state; 233251709ffdSYong Li } 233351709ffdSYong Li else if (property.first == "ExpireAction") 233451709ffdSYong Li { 233551709ffdSYong Li const std::string* s = 233651709ffdSYong Li std::get_if<std::string>(&property.second); 233751709ffdSYong Li if (!s) 233851709ffdSYong Li { 233951709ffdSYong Li messages::internalError(aResp->res); 2340601af5edSChicago Duan return; 234151709ffdSYong Li } 234251709ffdSYong Li 234351709ffdSYong Li std::string action = dbusToRfWatchdogAction(*s); 234451709ffdSYong Li if (action.empty()) 234551709ffdSYong Li { 234651709ffdSYong Li messages::internalError(aResp->res); 2347601af5edSChicago Duan return; 234851709ffdSYong Li } 234951709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 235051709ffdSYong Li } 235151709ffdSYong Li } 235251709ffdSYong Li }, 235351709ffdSYong Li "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0", 235451709ffdSYong Li "org.freedesktop.DBus.Properties", "GetAll", 235551709ffdSYong Li "xyz.openbmc_project.State.Watchdog"); 235651709ffdSYong Li } 235751709ffdSYong Li 235851709ffdSYong Li /** 2359c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2360c45f0082SYong Li * 2361c45f0082SYong Li * @param[in] aResp Shared pointer for generating response message. 2362c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2363c45f0082SYong Li * RF request. 2364c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2365c45f0082SYong Li * 2366c45f0082SYong Li * @return None. 2367c45f0082SYong Li */ 23688d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 2369c45f0082SYong Li const std::optional<bool> wdtEnable, 2370c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2371c45f0082SYong Li { 2372c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2373c45f0082SYong Li 2374c45f0082SYong Li if (wdtTimeOutAction) 2375c45f0082SYong Li { 2376c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2377c45f0082SYong Li // check if TimeOut Action is Valid 2378c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2379c45f0082SYong Li { 2380c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2381c45f0082SYong Li << *wdtTimeOutAction; 2382c45f0082SYong Li messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction, 2383c45f0082SYong Li "TimeoutAction"); 2384c45f0082SYong Li return; 2385c45f0082SYong Li } 2386c45f0082SYong Li 2387c45f0082SYong Li crow::connections::systemBus->async_method_call( 2388c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2389c45f0082SYong Li if (ec) 2390c45f0082SYong Li { 2391c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2392c45f0082SYong Li messages::internalError(aResp->res); 2393c45f0082SYong Li return; 2394c45f0082SYong Li } 2395c45f0082SYong Li }, 2396c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2397c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2398c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2399c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2400c45f0082SYong Li std::variant<std::string>(wdtTimeOutActStr)); 2401c45f0082SYong Li } 2402c45f0082SYong Li 2403c45f0082SYong Li if (wdtEnable) 2404c45f0082SYong Li { 2405c45f0082SYong Li crow::connections::systemBus->async_method_call( 2406c45f0082SYong Li [aResp](const boost::system::error_code ec) { 2407c45f0082SYong Li if (ec) 2408c45f0082SYong Li { 2409c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2410c45f0082SYong Li messages::internalError(aResp->res); 2411c45f0082SYong Li return; 2412c45f0082SYong Li } 2413c45f0082SYong Li }, 2414c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2415c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2416c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2417c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2418c45f0082SYong Li std::variant<bool>(*wdtEnable)); 2419c45f0082SYong Li } 2420c45f0082SYong Li } 2421c45f0082SYong Li 2422c45f0082SYong Li /** 2423c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 2424c5b2abe0SLewanczyk, Dawid * Schema 2425c5b2abe0SLewanczyk, Dawid */ 24267e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app) 24271abe55efSEd Tanous { 24287e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2429ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 24307e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 24314f48d5f6SEd Tanous [](const crow::Request& /*req*/, 24327e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 24338d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 24340f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 24358d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 24368d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2437462023adSSunitha Harish 2438462023adSSunitha Harish crow::connections::systemBus->async_method_call( 24394f48d5f6SEd Tanous [asyncResp](const boost::system::error_code ec, 2440cb13a392SEd Tanous const std::variant<std::string>& /*hostName*/) { 24412c70f800SEd Tanous nlohmann::json& ifaceArray = 2442462023adSSunitha Harish asyncResp->res.jsonValue["Members"]; 24432c70f800SEd Tanous ifaceArray = nlohmann::json::array(); 24447e860f15SJohn Edward Broadbent auto& count = 24457e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Members@odata.count"]; 24462c70f800SEd Tanous ifaceArray.push_back( 2447cb13a392SEd Tanous {{"@odata.id", "/redfish/v1/Systems/system"}}); 244894bda602STim Lee count = ifaceArray.size(); 2449cb13a392SEd Tanous if (!ec) 2450462023adSSunitha Harish { 2451462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 24522c70f800SEd Tanous ifaceArray.push_back( 24537e860f15SJohn Edward Broadbent {{"@odata.id", 24547e860f15SJohn Edward Broadbent "/redfish/v1/Systems/hypervisor"}}); 24552c70f800SEd Tanous count = ifaceArray.size(); 2456cb13a392SEd Tanous } 2457462023adSSunitha Harish }, 24588e651fbfSSunitha Harish "xyz.openbmc_project.Settings", 24598e651fbfSSunitha Harish "/xyz/openbmc_project/network/hypervisor", 2460462023adSSunitha Harish "org.freedesktop.DBus.Properties", "Get", 24617e860f15SJohn Edward Broadbent "xyz.openbmc_project.Network.SystemConfiguration", 24627e860f15SJohn Edward Broadbent "HostName"); 24637e860f15SJohn Edward Broadbent }); 2464c5b2abe0SLewanczyk, Dawid } 24657e860f15SJohn Edward Broadbent 24667e860f15SJohn Edward Broadbent /** 24677e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 24687e860f15SJohn Edward Broadbent */ 24694f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 24707e860f15SJohn Edward Broadbent { 24717e860f15SJohn Edward Broadbent constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 24727e860f15SJohn Edward Broadbent constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 24737e860f15SJohn Edward Broadbent constexpr char const* interfaceName = 24747e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 24757e860f15SJohn Edward Broadbent constexpr char const* method = "NMI"; 24767e860f15SJohn Edward Broadbent 24777e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 24787e860f15SJohn Edward Broadbent [asyncResp](const boost::system::error_code ec) { 24797e860f15SJohn Edward Broadbent if (ec) 24807e860f15SJohn Edward Broadbent { 24817e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 24827e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 24837e860f15SJohn Edward Broadbent return; 24847e860f15SJohn Edward Broadbent } 24857e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 24867e860f15SJohn Edward Broadbent }, 24877e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 24887e860f15SJohn Edward Broadbent } 2489c5b2abe0SLewanczyk, Dawid 2490c5b2abe0SLewanczyk, Dawid /** 2491cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 2492cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 2493cc340dd9SEd Tanous */ 24947e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app) 2495cc340dd9SEd Tanous { 2496cc340dd9SEd Tanous /** 2497cc340dd9SEd Tanous * Function handles POST method request. 2498cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 2499cc340dd9SEd Tanous */ 25007e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 25017e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/") 2502ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 25037e860f15SJohn Edward Broadbent .methods( 25047e860f15SJohn Edward Broadbent boost::beast::http::verb:: 25057e860f15SJohn Edward Broadbent post)([](const crow::Request& req, 25067e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 25079712f8acSEd Tanous std::string resetType; 25087e860f15SJohn Edward Broadbent if (!json_util::readJson(req, asyncResp->res, "ResetType", 25097e860f15SJohn Edward Broadbent resetType)) 2510cc340dd9SEd Tanous { 2511cc340dd9SEd Tanous return; 2512cc340dd9SEd Tanous } 2513cc340dd9SEd Tanous 2514d22c8396SJason M. Bills // Get the command and host vs. chassis 2515cc340dd9SEd Tanous std::string command; 2516d22c8396SJason M. Bills bool hostCommand; 2517d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2518cc340dd9SEd Tanous { 2519cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2520d22c8396SJason M. Bills hostCommand = true; 2521d22c8396SJason M. Bills } 2522d22c8396SJason M. Bills else if (resetType == "ForceOff") 2523d22c8396SJason M. Bills { 2524d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2525d22c8396SJason M. Bills hostCommand = false; 2526d22c8396SJason M. Bills } 2527d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2528d22c8396SJason M. Bills { 252986a0851aSJason M. Bills command = 253086a0851aSJason M. Bills "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 253186a0851aSJason M. Bills hostCommand = true; 2532cc340dd9SEd Tanous } 25339712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2534cc340dd9SEd Tanous { 2535cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2536d22c8396SJason M. Bills hostCommand = true; 2537cc340dd9SEd Tanous } 25389712f8acSEd Tanous else if (resetType == "GracefulRestart") 2539cc340dd9SEd Tanous { 25407e860f15SJohn Edward Broadbent command = "xyz.openbmc_project.State.Host.Transition." 25417e860f15SJohn Edward Broadbent "GracefulWarmReboot"; 2542d22c8396SJason M. Bills hostCommand = true; 2543d22c8396SJason M. Bills } 2544d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2545d22c8396SJason M. Bills { 254686a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 254786a0851aSJason M. Bills hostCommand = true; 2548cc340dd9SEd Tanous } 2549bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2550bfd5b826SLakshminarayana R. Kammath { 2551bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2552bfd5b826SLakshminarayana R. Kammath return; 2553bfd5b826SLakshminarayana R. Kammath } 2554cc340dd9SEd Tanous else 2555cc340dd9SEd Tanous { 25568d1b46d7Szhanghch05 messages::actionParameterUnknown(asyncResp->res, "Reset", 25578d1b46d7Szhanghch05 resetType); 2558cc340dd9SEd Tanous return; 2559cc340dd9SEd Tanous } 2560cc340dd9SEd Tanous 2561d22c8396SJason M. Bills if (hostCommand) 2562d22c8396SJason M. Bills { 2563cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 2564d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2565cc340dd9SEd Tanous if (ec) 2566cc340dd9SEd Tanous { 2567cc340dd9SEd Tanous BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 25687e860f15SJohn Edward Broadbent if (ec.value() == 25697e860f15SJohn Edward Broadbent boost::asio::error::invalid_argument) 2570d22c8396SJason M. Bills { 2571d22c8396SJason M. Bills messages::actionParameterNotSupported( 2572d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2573d22c8396SJason M. Bills } 2574d22c8396SJason M. Bills else 2575d22c8396SJason M. Bills { 2576f12894f8SJason M. Bills messages::internalError(asyncResp->res); 2577d22c8396SJason M. Bills } 2578cc340dd9SEd Tanous return; 2579cc340dd9SEd Tanous } 2580f12894f8SJason M. Bills messages::success(asyncResp->res); 2581cc340dd9SEd Tanous }, 2582cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 2583cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 2584cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 25859712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 2586abf2add6SEd Tanous std::variant<std::string>{command}); 2587cc340dd9SEd Tanous } 2588d22c8396SJason M. Bills else 2589d22c8396SJason M. Bills { 2590d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 2591d22c8396SJason M. Bills [asyncResp, resetType](const boost::system::error_code ec) { 2592d22c8396SJason M. Bills if (ec) 2593d22c8396SJason M. Bills { 2594d22c8396SJason M. Bills BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 25957e860f15SJohn Edward Broadbent if (ec.value() == 25967e860f15SJohn Edward Broadbent boost::asio::error::invalid_argument) 2597d22c8396SJason M. Bills { 2598d22c8396SJason M. Bills messages::actionParameterNotSupported( 2599d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2600d22c8396SJason M. Bills } 2601d22c8396SJason M. Bills else 2602d22c8396SJason M. Bills { 2603d22c8396SJason M. Bills messages::internalError(asyncResp->res); 2604d22c8396SJason M. Bills } 2605d22c8396SJason M. Bills return; 2606d22c8396SJason M. Bills } 2607d22c8396SJason M. Bills messages::success(asyncResp->res); 2608d22c8396SJason M. Bills }, 2609d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 2610d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 2611d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 26127e860f15SJohn Edward Broadbent "xyz.openbmc_project.State.Chassis", 26137e860f15SJohn Edward Broadbent "RequestedPowerTransition", 2614d22c8396SJason M. Bills std::variant<std::string>{command}); 2615d22c8396SJason M. Bills } 26167e860f15SJohn Edward Broadbent }); 2617d22c8396SJason M. Bills } 2618cc340dd9SEd Tanous 2619cc340dd9SEd Tanous /** 26206617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 2621c5b2abe0SLewanczyk, Dawid */ 26227e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app) 26231abe55efSEd Tanous { 2624c5b2abe0SLewanczyk, Dawid 2625c5b2abe0SLewanczyk, Dawid /** 2626c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 2627c5b2abe0SLewanczyk, Dawid */ 26287e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 2629ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystem) 26307e860f15SJohn Edward Broadbent .methods( 26317e860f15SJohn Edward Broadbent boost::beast::http::verb:: 26327e860f15SJohn Edward Broadbent get)([](const crow::Request&, 26337e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 26348d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 26353a2d0424SChris Cain "#ComputerSystem.v1_15_0.ComputerSystem"; 26368d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 26378d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 26388d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 26398d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 26408d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 26418d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 26428d1b46d7Szhanghch05 "Disabled"; 26438d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 26448d1b46d7Szhanghch05 uint64_t(0); 26458d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 26468d1b46d7Szhanghch05 "Disabled"; 26477e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.id"] = 26487e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system"; 264904a258f4SEd Tanous 26508d1b46d7Szhanghch05 asyncResp->res.jsonValue["Processors"] = { 2651029573d4SEd Tanous {"@odata.id", "/redfish/v1/Systems/system/Processors"}}; 26528d1b46d7Szhanghch05 asyncResp->res.jsonValue["Memory"] = { 2653029573d4SEd Tanous {"@odata.id", "/redfish/v1/Systems/system/Memory"}}; 26548d1b46d7Szhanghch05 asyncResp->res.jsonValue["Storage"] = { 2655a25aeccfSNikhil Potade {"@odata.id", "/redfish/v1/Systems/system/Storage"}}; 2656029573d4SEd Tanous 26578d1b46d7Szhanghch05 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = { 2658cc340dd9SEd Tanous {"target", 2659029573d4SEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"}, 26601cb1a9e6SAppaRao Puli {"@Redfish.ActionInfo", 26611cb1a9e6SAppaRao Puli "/redfish/v1/Systems/system/ResetActionInfo"}}; 2662c5b2abe0SLewanczyk, Dawid 26638d1b46d7Szhanghch05 asyncResp->res.jsonValue["LogServices"] = { 2664029573d4SEd Tanous {"@odata.id", "/redfish/v1/Systems/system/LogServices"}}; 2665c4bf6374SJason M. Bills 26668d1b46d7Szhanghch05 asyncResp->res.jsonValue["Bios"] = { 2667d82a3acdSCarol Wang {"@odata.id", "/redfish/v1/Systems/system/Bios"}}; 2668d82a3acdSCarol Wang 26698d1b46d7Szhanghch05 asyncResp->res.jsonValue["Links"]["ManagedBy"] = { 2670c5d03ff4SJennifer Lee {{"@odata.id", "/redfish/v1/Managers/bmc"}}}; 2671c5d03ff4SJennifer Lee 26728d1b46d7Szhanghch05 asyncResp->res.jsonValue["Status"] = { 2673c5d03ff4SJennifer Lee {"Health", "OK"}, 2674c5d03ff4SJennifer Lee {"State", "Enabled"}, 2675c5d03ff4SJennifer Lee }; 26760e8ac5e7SGunnar Mills 26770e8ac5e7SGunnar Mills // Fill in SerialConsole info 26780e8ac5e7SGunnar Mills asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 26790e8ac5e7SGunnar Mills 15; 26800e8ac5e7SGunnar Mills asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = { 26810e8ac5e7SGunnar Mills {"ServiceEnabled", true}, 26820e8ac5e7SGunnar Mills }; 26830e8ac5e7SGunnar Mills // TODO (Gunnar): Should look for obmc-console-ssh@2200.service 26840e8ac5e7SGunnar Mills asyncResp->res.jsonValue["SerialConsole"]["SSH"] = { 26850e8ac5e7SGunnar Mills {"ServiceEnabled", true}, 26860e8ac5e7SGunnar Mills {"Port", 2200}, 26870e8ac5e7SGunnar Mills // https://github.com/openbmc/docs/blob/master/console.md 26880e8ac5e7SGunnar Mills {"HotKeySequenceDisplay", "Press ~. to exit console"}, 26890e8ac5e7SGunnar Mills }; 26900e8ac5e7SGunnar Mills 26910e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 26920e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 26930e8ac5e7SGunnar Mills asyncResp->res.jsonValue["GraphicalConsole"] = { 26940e8ac5e7SGunnar Mills {"ServiceEnabled", true}, 26950e8ac5e7SGunnar Mills {"MaxConcurrentSessions", 4}, 26960e8ac5e7SGunnar Mills {"ConnectTypesSupported", {"KVMIP"}}, 26970e8ac5e7SGunnar Mills }; 26980e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 2699e284a7c1SJames Feist constexpr const std::array<const char*, 4> inventoryForSystems = { 2700b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 27012ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 2702e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 2703e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 2704b49ac873SJames Feist 2705b49ac873SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 2706b49ac873SJames Feist crow::connections::systemBus->async_method_call( 2707b49ac873SJames Feist [health](const boost::system::error_code ec, 2708b49ac873SJames Feist std::vector<std::string>& resp) { 2709b49ac873SJames Feist if (ec) 2710b49ac873SJames Feist { 2711b49ac873SJames Feist // no inventory 2712b49ac873SJames Feist return; 2713b49ac873SJames Feist } 2714b49ac873SJames Feist 2715b49ac873SJames Feist health->inventory = std::move(resp); 2716b49ac873SJames Feist }, 2717b49ac873SJames Feist "xyz.openbmc_project.ObjectMapper", 2718b49ac873SJames Feist "/xyz/openbmc_project/object_mapper", 2719b49ac873SJames Feist "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/", 2720b49ac873SJames Feist int32_t(0), inventoryForSystems); 2721b49ac873SJames Feist 2722b49ac873SJames Feist health->populate(); 2723b49ac873SJames Feist 27248d1b46d7Szhanghch05 getMainChassisId( 27258d1b46d7Szhanghch05 asyncResp, [](const std::string& chassisId, 27268d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 2727c5d03ff4SJennifer Lee aRsp->res.jsonValue["Links"]["Chassis"] = { 2728c5d03ff4SJennifer Lee {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}}; 2729c5d03ff4SJennifer Lee }); 2730a3002228SAppaRao Puli 27319f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 27329f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 2733a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 27345bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 27356c34de48SEd Tanous getHostState(asyncResp); 2736491d8ee7SSantosh Puranik getBootProperties(asyncResp); 2737978b8803SAndrew Geissler getBootProgress(asyncResp); 2738adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "PCIeDevices"); 273951709ffdSYong Li getHostWatchdogTimer(asyncResp); 2740c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 27416bd5a8d2SGunnar Mills getAutomaticRetry(asyncResp); 2742c0557e1aSGunnar Mills getLastResetTime(asyncResp); 2743a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 2744a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 2745a6349918SAppaRao Puli #endif 27461981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 27473a2d0424SChris Cain getPowerMode(asyncResp); 27487e860f15SJohn Edward Broadbent }); 27497e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 2750ed398213SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 27517e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 27527e860f15SJohn Edward Broadbent [](const crow::Request& req, 27537e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 27549f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 2755cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 2756491d8ee7SSantosh Puranik std::optional<nlohmann::json> bootProps; 2757c45f0082SYong Li std::optional<nlohmann::json> wdtTimerProps; 275898e386ecSGunnar Mills std::optional<std::string> assetTag; 2759c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 27603a2d0424SChris Cain std::optional<std::string> powerMode; 276141352c24SSantosh Puranik 27629f8bfa7cSGunnar Mills if (!json_util::readJson( 27638d1b46d7Szhanghch05 req, asyncResp->res, "IndicatorLED", indicatorLed, 27647e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 27657e860f15SJohn Edward Broadbent "Boot", bootProps, "WatchdogTimer", wdtTimerProps, 27667e860f15SJohn Edward Broadbent "PowerRestorePolicy", powerRestorePolicy, "AssetTag", 27673a2d0424SChris Cain assetTag, "PowerMode", powerMode)) 27686617338dSEd Tanous { 27696617338dSEd Tanous return; 27706617338dSEd Tanous } 2771491d8ee7SSantosh Puranik 27728d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 2773c45f0082SYong Li 277498e386ecSGunnar Mills if (assetTag) 277598e386ecSGunnar Mills { 277698e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 277798e386ecSGunnar Mills } 277898e386ecSGunnar Mills 2779c45f0082SYong Li if (wdtTimerProps) 2780c45f0082SYong Li { 2781c45f0082SYong Li std::optional<bool> wdtEnable; 2782c45f0082SYong Li std::optional<std::string> wdtTimeOutAction; 2783c45f0082SYong Li 2784c45f0082SYong Li if (!json_util::readJson(*wdtTimerProps, asyncResp->res, 2785c45f0082SYong Li "FunctionEnabled", wdtEnable, 2786c45f0082SYong Li "TimeoutAction", wdtTimeOutAction)) 2787c45f0082SYong Li { 2788c45f0082SYong Li return; 2789c45f0082SYong Li } 2790f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 2791c45f0082SYong Li } 2792c45f0082SYong Li 2793491d8ee7SSantosh Puranik if (bootProps) 2794491d8ee7SSantosh Puranik { 2795491d8ee7SSantosh Puranik std::optional<std::string> bootSource; 2796cd9a4666SKonstantin Aladyshev std::optional<std::string> bootType; 2797491d8ee7SSantosh Puranik std::optional<std::string> bootEnable; 279869f35306SGunnar Mills std::optional<std::string> automaticRetryConfig; 2799491d8ee7SSantosh Puranik 280069f35306SGunnar Mills if (!json_util::readJson( 28017e860f15SJohn Edward Broadbent *bootProps, asyncResp->res, 28027e860f15SJohn Edward Broadbent "BootSourceOverrideTarget", bootSource, 2803cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode", bootType, 28047e860f15SJohn Edward Broadbent "BootSourceOverrideEnabled", bootEnable, 280569f35306SGunnar Mills "AutomaticRetryConfig", automaticRetryConfig)) 2806491d8ee7SSantosh Puranik { 2807491d8ee7SSantosh Puranik return; 2808491d8ee7SSantosh Puranik } 2809*c21865c4SKonstantin Aladyshev 2810cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 281169f35306SGunnar Mills { 2812*c21865c4SKonstantin Aladyshev setBootProperties(asyncResp, bootSource, bootType, 2813*c21865c4SKonstantin Aladyshev bootEnable); 2814491d8ee7SSantosh Puranik } 281569f35306SGunnar Mills if (automaticRetryConfig) 281669f35306SGunnar Mills { 2817f23b7296SEd Tanous setAutomaticRetry(asyncResp, *automaticRetryConfig); 281869f35306SGunnar Mills } 281969f35306SGunnar Mills } 2820265c1602SJohnathan Mantey 28219f8bfa7cSGunnar Mills if (locationIndicatorActive) 28229f8bfa7cSGunnar Mills { 28237e860f15SJohn Edward Broadbent setLocationIndicatorActive(asyncResp, 28247e860f15SJohn Edward Broadbent *locationIndicatorActive); 28259f8bfa7cSGunnar Mills } 28269f8bfa7cSGunnar Mills 28277e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 28287e860f15SJohn Edward Broadbent // passed 28299712f8acSEd Tanous if (indicatorLed) 28306617338dSEd Tanous { 2831f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 28327e860f15SJohn Edward Broadbent asyncResp->res.addHeader( 28337e860f15SJohn Edward Broadbent boost::beast::http::field::warning, 2834d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 2835d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 28366617338dSEd Tanous } 2837c6a620f2SGeorge Liu 2838c6a620f2SGeorge Liu if (powerRestorePolicy) 2839c6a620f2SGeorge Liu { 28404e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 2841c6a620f2SGeorge Liu } 28423a2d0424SChris Cain 28433a2d0424SChris Cain if (powerMode) 28443a2d0424SChris Cain { 28453a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 28463a2d0424SChris Cain } 28477e860f15SJohn Edward Broadbent }); 2848c5b2abe0SLewanczyk, Dawid } 28491cb1a9e6SAppaRao Puli 28501cb1a9e6SAppaRao Puli /** 28511cb1a9e6SAppaRao Puli * SystemResetActionInfo derived class for delivering Computer Systems 28521cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 28531cb1a9e6SAppaRao Puli */ 28547e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app) 28551cb1a9e6SAppaRao Puli { 28561cb1a9e6SAppaRao Puli 28571cb1a9e6SAppaRao Puli /** 28581cb1a9e6SAppaRao Puli * Functions triggers appropriate requests on DBus 28591cb1a9e6SAppaRao Puli */ 28607e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/") 2861ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 28627e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 28637e860f15SJohn Edward Broadbent [](const crow::Request&, 28647e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 28658d1b46d7Szhanghch05 asyncResp->res.jsonValue = { 28661cb1a9e6SAppaRao Puli {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"}, 28671cb1a9e6SAppaRao Puli {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"}, 28681cb1a9e6SAppaRao Puli {"Name", "Reset Action Info"}, 28691cb1a9e6SAppaRao Puli {"Id", "ResetActionInfo"}, 28701cb1a9e6SAppaRao Puli {"Parameters", 28711cb1a9e6SAppaRao Puli {{{"Name", "ResetType"}, 28721cb1a9e6SAppaRao Puli {"Required", true}, 28731cb1a9e6SAppaRao Puli {"DataType", "String"}, 28741cb1a9e6SAppaRao Puli {"AllowableValues", 28757e860f15SJohn Edward Broadbent {"On", "ForceOff", "ForceOn", "ForceRestart", 28767e860f15SJohn Edward Broadbent "GracefulRestart", "GracefulShutdown", "PowerCycle", 28777e860f15SJohn Edward Broadbent "Nmi"}}}}}}; 28787e860f15SJohn Edward Broadbent }); 28791cb1a9e6SAppaRao Puli } 2880c5b2abe0SLewanczyk, Dawid } // namespace redfish 2881