xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision dfababfc65fb9f07050070910be0cc015df4fd2c)
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 
181e1e598dSJonathan Doman #include "dbus_singleton.hpp"
19b49ac873SJames Feist #include "health.hpp"
201c8fba97SJames Feist #include "led.hpp"
21f5c9f8bdSJason M. Bills #include "pcie.hpp"
22f4c99e70SEd Tanous #include "query.hpp"
23c5d03ff4SJennifer Lee #include "redfish_util.hpp"
24c5d03ff4SJennifer Lee 
257e860f15SJohn Edward Broadbent #include <app.hpp>
269712f8acSEd Tanous #include <boost/container/flat_map.hpp>
27168e20c1SEd Tanous #include <dbus_utility.hpp>
28ed398213SEd Tanous #include <registries/privilege_registry.hpp>
291e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
30cb7e1e7bSAndrew Geissler #include <utils/fw_utils.hpp>
31c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
321214b7e7SGunnar Mills 
33abf2add6SEd Tanous #include <variant>
34c5b2abe0SLewanczyk, Dawid 
351abe55efSEd Tanous namespace redfish
361abe55efSEd Tanous {
37c5b2abe0SLewanczyk, Dawid 
389d3ae10eSAlpana Kumari /**
399d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
409d3ae10eSAlpana Kumari  *
419d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
429d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
439d3ae10eSAlpana Kumari  *
449d3ae10eSAlpana Kumari  * @return None.
459d3ae10eSAlpana Kumari  */
468d1b46d7Szhanghch05 inline void
478d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
481e1e598dSJonathan Doman                          bool isDimmFunctional)
499d3ae10eSAlpana Kumari {
501e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
519d3ae10eSAlpana Kumari 
529d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
539d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
549d3ae10eSAlpana Kumari     // ENABLED.
559d3ae10eSAlpana Kumari     nlohmann::json& prevMemSummary =
569d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
579d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
589d3ae10eSAlpana Kumari     {
59e05aec50SEd Tanous         if (isDimmFunctional)
609d3ae10eSAlpana Kumari         {
619d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
629d3ae10eSAlpana Kumari                 "Enabled";
639d3ae10eSAlpana Kumari         }
649d3ae10eSAlpana Kumari     }
659d3ae10eSAlpana Kumari }
669d3ae10eSAlpana Kumari 
6757e8c9beSAlpana Kumari /*
6857e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
6957e8c9beSAlpana Kumari  *
7057e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
7157e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
7257e8c9beSAlpana Kumari  *
7357e8c9beSAlpana Kumari  * @return None.
7457e8c9beSAlpana Kumari  */
751e1e598dSJonathan Doman inline void
761e1e598dSJonathan Doman     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
771e1e598dSJonathan Doman                            bool isCpuPresent)
7857e8c9beSAlpana Kumari {
791e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
8057e8c9beSAlpana Kumari 
8155f79e6fSEd Tanous     if (isCpuPresent)
8257e8c9beSAlpana Kumari     {
83b4b9595aSJames Feist         nlohmann::json& procCount =
84b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
8555f79e6fSEd Tanous         auto* procCountPtr =
86b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
87b4b9595aSJames Feist         if (procCountPtr != nullptr)
88b4b9595aSJames Feist         {
89b4b9595aSJames Feist             // shouldn't be possible to be nullptr
90b4b9595aSJames Feist             *procCountPtr += 1;
9157e8c9beSAlpana Kumari         }
92b4b9595aSJames Feist     }
9357e8c9beSAlpana Kumari }
9457e8c9beSAlpana Kumari 
9557e8c9beSAlpana Kumari /*
9657e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9757e8c9beSAlpana Kumari  *        CPU Functional State
9857e8c9beSAlpana Kumari  *
9957e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
10057e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
10157e8c9beSAlpana Kumari  *
10257e8c9beSAlpana Kumari  * @return None.
10357e8c9beSAlpana Kumari  */
1041e1e598dSJonathan Doman inline void
1051e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1061e1e598dSJonathan Doman                              bool isCpuFunctional)
10757e8c9beSAlpana Kumari {
1081e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
10957e8c9beSAlpana Kumari 
11057e8c9beSAlpana Kumari     nlohmann::json& prevProcState =
11157e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
11257e8c9beSAlpana Kumari 
11357e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
11457e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
11557e8c9beSAlpana Kumari     // Functional.
11657e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11757e8c9beSAlpana Kumari     {
118e05aec50SEd Tanous         if (isCpuFunctional)
11957e8c9beSAlpana Kumari         {
12057e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
12157e8c9beSAlpana Kumari                 "Enabled";
12257e8c9beSAlpana Kumari         }
12357e8c9beSAlpana Kumari     }
12457e8c9beSAlpana Kumari }
12557e8c9beSAlpana Kumari 
126b9d36b47SEd Tanous inline void
127b9d36b47SEd Tanous     getProcessorProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
128b9d36b47SEd Tanous                            const std::string& service, const std::string& path,
129b9d36b47SEd Tanous                            const dbus::utility::DBusPropertiesMap& properties)
13003fbed92SAli Ahmed {
13103fbed92SAli Ahmed 
13203fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
13303fbed92SAli Ahmed 
1341e1e598dSJonathan Doman     auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
1351e1e598dSJonathan Doman                                        const bool cpuPresenceCheck) {
13603fbed92SAli Ahmed         if (ec3)
13703fbed92SAli Ahmed         {
13803fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
13903fbed92SAli Ahmed             return;
14003fbed92SAli Ahmed         }
14103fbed92SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
14203fbed92SAli Ahmed     };
14303fbed92SAli Ahmed 
1441e1e598dSJonathan Doman     auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
1451e1e598dSJonathan Doman                                          const bool cpuFunctionalCheck) {
14603fbed92SAli Ahmed         if (ec3)
14703fbed92SAli Ahmed         {
14803fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
14903fbed92SAli Ahmed             return;
15003fbed92SAli Ahmed         }
15103fbed92SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
15203fbed92SAli Ahmed     };
15303fbed92SAli Ahmed 
15403fbed92SAli Ahmed     // Get the Presence of CPU
1551e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
1561e1e598dSJonathan Doman         *crow::connections::systemBus, service, path,
1571e1e598dSJonathan Doman         "xyz.openbmc_project.Inventory.Item", "Present",
1581e1e598dSJonathan Doman         std::move(getCpuPresenceState));
15903fbed92SAli Ahmed 
16003fbed92SAli Ahmed     // Get the Functional State
1611e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
1621e1e598dSJonathan Doman         *crow::connections::systemBus, service, path,
1631e1e598dSJonathan Doman         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
1641e1e598dSJonathan Doman         std::move(getCpuFunctionalState));
16503fbed92SAli Ahmed 
16603fbed92SAli Ahmed     for (const auto& property : properties)
16703fbed92SAli Ahmed     {
16803fbed92SAli Ahmed 
16903fbed92SAli Ahmed         // TODO: Get Model
17003fbed92SAli Ahmed 
17103fbed92SAli Ahmed         // Get CoreCount
17203fbed92SAli Ahmed         if (property.first == "CoreCount")
17303fbed92SAli Ahmed         {
17403fbed92SAli Ahmed 
17503fbed92SAli Ahmed             // Get CPU CoreCount and add it to the total
17603fbed92SAli Ahmed             const uint16_t* coreCountVal =
17703fbed92SAli Ahmed                 std::get_if<uint16_t>(&property.second);
17803fbed92SAli Ahmed 
179e662eae8SEd Tanous             if (coreCountVal == nullptr)
18003fbed92SAli Ahmed             {
18103fbed92SAli Ahmed                 messages::internalError(aResp->res);
18203fbed92SAli Ahmed                 return;
18303fbed92SAli Ahmed             }
18403fbed92SAli Ahmed 
18503fbed92SAli Ahmed             nlohmann::json& coreCount =
18603fbed92SAli Ahmed                 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
18703fbed92SAli Ahmed             uint64_t* coreCountPtr = coreCount.get_ptr<uint64_t*>();
18803fbed92SAli Ahmed 
18903fbed92SAli Ahmed             if (coreCountPtr == nullptr)
19003fbed92SAli Ahmed             {
19103fbed92SAli Ahmed                 coreCount = 0;
19203fbed92SAli Ahmed             }
19303fbed92SAli Ahmed             else
19403fbed92SAli Ahmed             {
19503fbed92SAli Ahmed                 *coreCountPtr += *coreCountVal;
19603fbed92SAli Ahmed             }
19703fbed92SAli Ahmed         }
19803fbed92SAli Ahmed     }
19903fbed92SAli Ahmed }
20003fbed92SAli Ahmed 
20103fbed92SAli Ahmed /*
20203fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
20303fbed92SAli Ahmed  *
20403fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
20503fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
20603fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
20703fbed92SAli Ahmed  *
20803fbed92SAli Ahmed  * @return None.
20903fbed92SAli Ahmed  */
21003fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21103fbed92SAli Ahmed                                 const std::string& service,
21203fbed92SAli Ahmed                                 const std::string& path)
21303fbed92SAli Ahmed {
21403fbed92SAli Ahmed 
21503fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
21603fbed92SAli Ahmed         [aResp, service,
21703fbed92SAli Ahmed          path](const boost::system::error_code ec2,
218b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
21903fbed92SAli Ahmed             if (ec2)
22003fbed92SAli Ahmed             {
22103fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
22203fbed92SAli Ahmed                 messages::internalError(aResp->res);
22303fbed92SAli Ahmed                 return;
22403fbed92SAli Ahmed             }
22503fbed92SAli Ahmed             getProcessorProperties(aResp, service, path, properties);
22603fbed92SAli Ahmed         },
22703fbed92SAli Ahmed         service, path, "org.freedesktop.DBus.Properties", "GetAll",
22803fbed92SAli Ahmed         "xyz.openbmc_project.Inventory.Item.Cpu");
22903fbed92SAli Ahmed }
23003fbed92SAli Ahmed 
23157e8c9beSAlpana Kumari /*
232c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
233c5b2abe0SLewanczyk, Dawid  *
234c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2358f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
236c5b2abe0SLewanczyk, Dawid  *
237c5b2abe0SLewanczyk, Dawid  * @return None.
238c5b2abe0SLewanczyk, Dawid  */
239b5a76932SEd Tanous inline void
2408d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
241b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2421abe55efSEd Tanous {
24355c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
2449d3ae10eSAlpana Kumari 
24555c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
246b9d36b47SEd Tanous         [aResp,
247b9d36b47SEd Tanous          systemHealth](const boost::system::error_code ec,
248b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
2491abe55efSEd Tanous             if (ec)
2501abe55efSEd Tanous             {
25155c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
252f12894f8SJason M. Bills                 messages::internalError(aResp->res);
253c5b2abe0SLewanczyk, Dawid                 return;
254c5b2abe0SLewanczyk, Dawid             }
255c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
2566c34de48SEd Tanous             for (const std::pair<std::string,
2576c34de48SEd Tanous                                  std::vector<std::pair<
2581214b7e7SGunnar Mills                                      std::string, std::vector<std::string>>>>&
2591214b7e7SGunnar Mills                      object : subtree)
2601abe55efSEd Tanous             {
261c5b2abe0SLewanczyk, Dawid                 const std::string& path = object.first;
26255c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
2631abe55efSEd Tanous                 const std::vector<
2641214b7e7SGunnar Mills                     std::pair<std::string, std::vector<std::string>>>&
2651214b7e7SGunnar Mills                     connectionNames = object.second;
26626f6976fSEd Tanous                 if (connectionNames.empty())
2671abe55efSEd Tanous                 {
268c5b2abe0SLewanczyk, Dawid                     continue;
269c5b2abe0SLewanczyk, Dawid                 }
270029573d4SEd Tanous 
2715bc2dc8eSJames Feist                 auto memoryHealth = std::make_shared<HealthPopulate>(
272*dfababfcSNan Zhou                     aResp, "/MemorySummary/Status"_json_pointer);
2735bc2dc8eSJames Feist 
2745bc2dc8eSJames Feist                 auto cpuHealth = std::make_shared<HealthPopulate>(
275*dfababfcSNan Zhou                     aResp, "/ProcessorSummary/Status"_json_pointer);
2765bc2dc8eSJames Feist 
2775bc2dc8eSJames Feist                 systemHealth->children.emplace_back(memoryHealth);
2785bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
2795bc2dc8eSJames Feist 
2806c34de48SEd Tanous                 // This is not system, so check if it's cpu, dimm, UUID or
2816c34de48SEd Tanous                 // BiosVer
28204a258f4SEd Tanous                 for (const auto& connection : connectionNames)
2831abe55efSEd Tanous                 {
28404a258f4SEd Tanous                     for (const auto& interfaceName : connection.second)
2851abe55efSEd Tanous                     {
28604a258f4SEd Tanous                         if (interfaceName ==
28704a258f4SEd Tanous                             "xyz.openbmc_project.Inventory.Item.Dimm")
2881abe55efSEd Tanous                         {
2891abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
29004a258f4SEd Tanous                                 << "Found Dimm, now get its properties.";
2919d3ae10eSAlpana Kumari 
29255c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
2939d3ae10eSAlpana Kumari                                 [aResp, service{connection.first},
294f23b7296SEd Tanous                                  path](const boost::system::error_code ec2,
295b9d36b47SEd Tanous                                        const dbus::utility::DBusPropertiesMap&
2961214b7e7SGunnar Mills                                            properties) {
297cb13a392SEd Tanous                                     if (ec2)
2981abe55efSEd Tanous                                     {
2991abe55efSEd Tanous                                         BMCWEB_LOG_ERROR
300cb13a392SEd Tanous                                             << "DBUS response error " << ec2;
301f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
302c5b2abe0SLewanczyk, Dawid                                         return;
303c5b2abe0SLewanczyk, Dawid                                     }
3046c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
3056c34de48SEd Tanous                                                      << properties.size()
306c5b2abe0SLewanczyk, Dawid                                                      << " Dimm properties.";
3079d3ae10eSAlpana Kumari 
30826f6976fSEd Tanous                                     if (!properties.empty())
3099d3ae10eSAlpana Kumari                                     {
310168e20c1SEd Tanous                                         for (const std::pair<
311168e20c1SEd Tanous                                                  std::string,
312168e20c1SEd Tanous                                                  dbus::utility::
313168e20c1SEd Tanous                                                      DbusVariantType>&
3141214b7e7SGunnar Mills                                                  property : properties)
3151abe55efSEd Tanous                                         {
3165fd7ba65SCheng C Yang                                             if (property.first !=
3175fd7ba65SCheng C Yang                                                 "MemorySizeInKB")
3181abe55efSEd Tanous                                             {
3195fd7ba65SCheng C Yang                                                 continue;
3205fd7ba65SCheng C Yang                                             }
3215fd7ba65SCheng C Yang                                             const uint32_t* value =
3228d78b7a9SPatrick Williams                                                 std::get_if<uint32_t>(
3231b6b96c5SEd Tanous                                                     &property.second);
3245fd7ba65SCheng C Yang                                             if (value == nullptr)
3251abe55efSEd Tanous                                             {
3265fd7ba65SCheng C Yang                                                 BMCWEB_LOG_DEBUG
3270fda0f12SGeorge Liu                                                     << "Find incorrect type of MemorySize";
3285fd7ba65SCheng C Yang                                                 continue;
3295fd7ba65SCheng C Yang                                             }
3305fd7ba65SCheng C Yang                                             nlohmann::json& totalMemory =
3310fda0f12SGeorge Liu                                                 aResp->res.jsonValue
3320fda0f12SGeorge Liu                                                     ["MemorySummary"]
3330fda0f12SGeorge Liu                                                     ["TotalSystemMemoryGiB"];
3345fd7ba65SCheng C Yang                                             uint64_t* preValue =
3355fd7ba65SCheng C Yang                                                 totalMemory
3365fd7ba65SCheng C Yang                                                     .get_ptr<uint64_t*>();
3375fd7ba65SCheng C Yang                                             if (preValue == nullptr)
3385fd7ba65SCheng C Yang                                             {
3395fd7ba65SCheng C Yang                                                 continue;
3405fd7ba65SCheng C Yang                                             }
3410fda0f12SGeorge Liu                                             aResp->res.jsonValue
3420fda0f12SGeorge Liu                                                 ["MemorySummary"]
3430fda0f12SGeorge Liu                                                 ["TotalSystemMemoryGiB"] =
3445fd7ba65SCheng C Yang                                                 *value / (1024 * 1024) +
3455fd7ba65SCheng C Yang                                                 *preValue;
3465fd7ba65SCheng C Yang                                             aResp->res
3475fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
3489d3ae10eSAlpana Kumari                                                           ["Status"]["State"] =
3491abe55efSEd Tanous                                                 "Enabled";
350c5b2abe0SLewanczyk, Dawid                                         }
351c5b2abe0SLewanczyk, Dawid                                     }
3529d3ae10eSAlpana Kumari                                     else
3539d3ae10eSAlpana Kumari                                     {
3541e1e598dSJonathan Doman                                         sdbusplus::asio::getProperty<bool>(
3551e1e598dSJonathan Doman                                             *crow::connections::systemBus,
3561e1e598dSJonathan Doman                                             service, path,
3571e1e598dSJonathan Doman                                             "xyz.openbmc_project.State."
3581e1e598dSJonathan Doman                                             "Decorator.OperationalStatus",
3591e1e598dSJonathan Doman                                             "Functional",
3609d3ae10eSAlpana Kumari                                             [aResp](
3619d3ae10eSAlpana Kumari                                                 const boost::system::error_code
362cb13a392SEd Tanous                                                     ec3,
3631e1e598dSJonathan Doman                                                 bool dimmState) {
364cb13a392SEd Tanous                                                 if (ec3)
3659d3ae10eSAlpana Kumari                                                 {
3669d3ae10eSAlpana Kumari                                                     BMCWEB_LOG_ERROR
3670fda0f12SGeorge Liu                                                         << "DBUS response error "
368cb13a392SEd Tanous                                                         << ec3;
3699d3ae10eSAlpana Kumari                                                     return;
3709d3ae10eSAlpana Kumari                                                 }
3719d3ae10eSAlpana Kumari                                                 updateDimmProperties(aResp,
3729d3ae10eSAlpana Kumari                                                                      dimmState);
3731e1e598dSJonathan Doman                                             });
3749d3ae10eSAlpana Kumari                                     }
375c5b2abe0SLewanczyk, Dawid                                 },
37604a258f4SEd Tanous                                 connection.first, path,
3776c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
3786c34de48SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm");
3795bc2dc8eSJames Feist 
3805bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
3811abe55efSEd Tanous                         }
38204a258f4SEd Tanous                         else if (interfaceName ==
38304a258f4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.Cpu")
3841abe55efSEd Tanous                         {
3851abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
38604a258f4SEd Tanous                                 << "Found Cpu, now get its properties.";
38757e8c9beSAlpana Kumari 
38803fbed92SAli Ahmed                             getProcessorSummary(aResp, connection.first, path);
3895bc2dc8eSJames Feist 
3905bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
3911abe55efSEd Tanous                         }
39204a258f4SEd Tanous                         else if (interfaceName ==
39304a258f4SEd Tanous                                  "xyz.openbmc_project.Common.UUID")
3941abe55efSEd Tanous                         {
3951abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
39604a258f4SEd Tanous                                 << "Found UUID, now get its properties.";
39755c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
398168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec3,
399b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
4001214b7e7SGunnar Mills                                             properties) {
401cb13a392SEd Tanous                                     if (ec3)
4021abe55efSEd Tanous                                     {
4031abe55efSEd Tanous                                         BMCWEB_LOG_DEBUG
404cb13a392SEd Tanous                                             << "DBUS response error " << ec3;
405f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
406c5b2abe0SLewanczyk, Dawid                                         return;
407c5b2abe0SLewanczyk, Dawid                                     }
4086c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
4096c34de48SEd Tanous                                                      << properties.size()
410c5b2abe0SLewanczyk, Dawid                                                      << " UUID properties.";
411168e20c1SEd Tanous                                     for (const std::pair<
412168e20c1SEd Tanous                                              std::string,
413168e20c1SEd Tanous                                              dbus::utility::DbusVariantType>&
4141214b7e7SGunnar Mills                                              property : properties)
4151abe55efSEd Tanous                                     {
41604a258f4SEd Tanous                                         if (property.first == "UUID")
4171abe55efSEd Tanous                                         {
418c5b2abe0SLewanczyk, Dawid                                             const std::string* value =
4198d78b7a9SPatrick Williams                                                 std::get_if<std::string>(
4201b6b96c5SEd Tanous                                                     &property.second);
42104a258f4SEd Tanous 
4221abe55efSEd Tanous                                             if (value != nullptr)
4231abe55efSEd Tanous                                             {
424029573d4SEd Tanous                                                 std::string valueStr = *value;
42504a258f4SEd Tanous                                                 if (valueStr.size() == 32)
4261abe55efSEd Tanous                                                 {
427029573d4SEd Tanous                                                     valueStr.insert(8, 1, '-');
428029573d4SEd Tanous                                                     valueStr.insert(13, 1, '-');
429029573d4SEd Tanous                                                     valueStr.insert(18, 1, '-');
430029573d4SEd Tanous                                                     valueStr.insert(23, 1, '-');
43104a258f4SEd Tanous                                                 }
432029573d4SEd Tanous                                                 BMCWEB_LOG_DEBUG << "UUID = "
43304a258f4SEd Tanous                                                                  << valueStr;
434029573d4SEd Tanous                                                 aResp->res.jsonValue["UUID"] =
43504a258f4SEd Tanous                                                     valueStr;
436c5b2abe0SLewanczyk, Dawid                                             }
437c5b2abe0SLewanczyk, Dawid                                         }
438c5b2abe0SLewanczyk, Dawid                                     }
439c5b2abe0SLewanczyk, Dawid                                 },
44004a258f4SEd Tanous                                 connection.first, path,
4416c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4421abe55efSEd Tanous                                 "xyz.openbmc_project.Common.UUID");
443c5b2abe0SLewanczyk, Dawid                         }
444029573d4SEd Tanous                         else if (interfaceName ==
445029573d4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.System")
4461abe55efSEd Tanous                         {
447029573d4SEd Tanous                             crow::connections::systemBus->async_method_call(
448168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec2,
449b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
4501214b7e7SGunnar Mills                                             propertiesList) {
451cb13a392SEd Tanous                                     if (ec2)
452029573d4SEd Tanous                                     {
453e4a4b9a9SJames Feist                                         // doesn't have to include this
454e4a4b9a9SJames Feist                                         // interface
455029573d4SEd Tanous                                         return;
456029573d4SEd Tanous                                     }
457698654b6SGunnar Mills                                     BMCWEB_LOG_DEBUG
458698654b6SGunnar Mills                                         << "Got " << propertiesList.size()
459029573d4SEd Tanous                                         << " properties for system";
460168e20c1SEd Tanous                                     for (const std::pair<
461168e20c1SEd Tanous                                              std::string,
462168e20c1SEd Tanous                                              dbus::utility::DbusVariantType>&
4631214b7e7SGunnar Mills                                              property : propertiesList)
464029573d4SEd Tanous                                     {
465fc5afcf9Sbeccabroek                                         const std::string& propertyName =
466fc5afcf9Sbeccabroek                                             property.first;
467fc5afcf9Sbeccabroek                                         if ((propertyName == "PartNumber") ||
468fc5afcf9Sbeccabroek                                             (propertyName == "SerialNumber") ||
469fc5afcf9Sbeccabroek                                             (propertyName == "Manufacturer") ||
4705235d964SSunnySrivastava1984                                             (propertyName == "Model") ||
4715235d964SSunnySrivastava1984                                             (propertyName == "SubModel"))
472fc5afcf9Sbeccabroek                                         {
473029573d4SEd Tanous                                             const std::string* value =
474fc5afcf9Sbeccabroek                                                 std::get_if<std::string>(
475029573d4SEd Tanous                                                     &property.second);
476029573d4SEd Tanous                                             if (value != nullptr)
477029573d4SEd Tanous                                             {
478029573d4SEd Tanous                                                 aResp->res
479fc5afcf9Sbeccabroek                                                     .jsonValue[propertyName] =
480029573d4SEd Tanous                                                     *value;
481029573d4SEd Tanous                                             }
482029573d4SEd Tanous                                         }
483fc5afcf9Sbeccabroek                                     }
484c1e236a6SGunnar Mills 
485cb7e1e7bSAndrew Geissler                                     // Grab the bios version
486f97ddba7SGunnar Mills                                     fw_util::populateFirmwareInformation(
487cb7e1e7bSAndrew Geissler                                         aResp, fw_util::biosPurpose,
48872d566d9SGunnar Mills                                         "BiosVersion", false);
489029573d4SEd Tanous                                 },
490029573d4SEd Tanous                                 connection.first, path,
491029573d4SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4920fda0f12SGeorge Liu                                 "xyz.openbmc_project.Inventory.Decorator.Asset");
493e4a4b9a9SJames Feist 
4941e1e598dSJonathan Doman                             sdbusplus::asio::getProperty<std::string>(
4951e1e598dSJonathan Doman                                 *crow::connections::systemBus, connection.first,
4961e1e598dSJonathan Doman                                 path,
4971e1e598dSJonathan Doman                                 "xyz.openbmc_project.Inventory.Decorator."
4981e1e598dSJonathan Doman                                 "AssetTag",
4991e1e598dSJonathan Doman                                 "AssetTag",
500168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec2,
5011e1e598dSJonathan Doman                                         const std::string& value) {
502cb13a392SEd Tanous                                     if (ec2)
503e4a4b9a9SJames Feist                                     {
504e4a4b9a9SJames Feist                                         // doesn't have to include this
505e4a4b9a9SJames Feist                                         // interface
506e4a4b9a9SJames Feist                                         return;
507e4a4b9a9SJames Feist                                     }
508e4a4b9a9SJames Feist 
5091e1e598dSJonathan Doman                                     aResp->res.jsonValue["AssetTag"] = value;
5101e1e598dSJonathan Doman                                 });
511029573d4SEd Tanous                         }
512029573d4SEd Tanous                     }
513029573d4SEd Tanous                 }
514c5b2abe0SLewanczyk, Dawid             }
515c5b2abe0SLewanczyk, Dawid         },
516c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
517c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
518c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5196617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
5206617338dSEd Tanous         std::array<const char*, 5>{
5216617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
5226617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
5236617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
5246617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
5256617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
5266617338dSEd Tanous         });
527c5b2abe0SLewanczyk, Dawid }
528c5b2abe0SLewanczyk, Dawid 
529c5b2abe0SLewanczyk, Dawid /**
530c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
531c5b2abe0SLewanczyk, Dawid  *
532c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
533c5b2abe0SLewanczyk, Dawid  *
534c5b2abe0SLewanczyk, Dawid  * @return None.
535c5b2abe0SLewanczyk, Dawid  */
5368d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5371abe55efSEd Tanous {
53855c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5391e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5401e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5411e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5421e1e598dSJonathan Doman         "CurrentHostState",
543c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
5441e1e598dSJonathan Doman                 const std::string& hostState) {
5451abe55efSEd Tanous             if (ec)
5461abe55efSEd Tanous             {
54722228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
54822228c28SAndrew Geissler                 {
54922228c28SAndrew Geissler                     // Service not available, no error, just don't return
55022228c28SAndrew Geissler                     // host state info
55122228c28SAndrew Geissler                     BMCWEB_LOG_DEBUG << "Service not available " << ec;
55222228c28SAndrew Geissler                     return;
55322228c28SAndrew Geissler                 }
55422228c28SAndrew Geissler                 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
555f12894f8SJason M. Bills                 messages::internalError(aResp->res);
556c5b2abe0SLewanczyk, Dawid                 return;
557c5b2abe0SLewanczyk, Dawid             }
5586617338dSEd Tanous 
5591e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Host state: " << hostState;
560c5b2abe0SLewanczyk, Dawid             // Verify Host State
5611e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5621abe55efSEd Tanous             {
56355c7b7a2SEd Tanous                 aResp->res.jsonValue["PowerState"] = "On";
5646617338dSEd Tanous                 aResp->res.jsonValue["Status"]["State"] = "Enabled";
5651abe55efSEd Tanous             }
5661e1e598dSJonathan Doman             else if (hostState ==
5670fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
5688c888608SGunnar Mills             {
5698c888608SGunnar Mills                 aResp->res.jsonValue["PowerState"] = "On";
5708c888608SGunnar Mills                 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
5718c888608SGunnar Mills             }
5721e1e598dSJonathan Doman             else if (hostState ==
5730fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
57483935af9SAndrew Geissler             {
57583935af9SAndrew Geissler                 aResp->res.jsonValue["PowerState"] = "On";
57683935af9SAndrew Geissler                 aResp->res.jsonValue["Status"]["State"] = "InTest";
57783935af9SAndrew Geissler             }
5780fda0f12SGeorge Liu             else if (
5791e1e598dSJonathan Doman                 hostState ==
5800fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5811a2a1437SAndrew Geissler             {
5821a2a1437SAndrew Geissler                 aResp->res.jsonValue["PowerState"] = "PoweringOn";
58315c27bf8SNoah Brewer                 aResp->res.jsonValue["Status"]["State"] = "Starting";
5841a2a1437SAndrew Geissler             }
5850fda0f12SGeorge Liu             else if (
5861e1e598dSJonathan Doman                 hostState ==
5870fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5881a2a1437SAndrew Geissler             {
5891a2a1437SAndrew Geissler                 aResp->res.jsonValue["PowerState"] = "PoweringOff";
5901a2a1437SAndrew Geissler                 aResp->res.jsonValue["Status"]["State"] = "Disabled";
5911a2a1437SAndrew Geissler             }
5921abe55efSEd Tanous             else
5931abe55efSEd Tanous             {
59455c7b7a2SEd Tanous                 aResp->res.jsonValue["PowerState"] = "Off";
5956617338dSEd Tanous                 aResp->res.jsonValue["Status"]["State"] = "Disabled";
596c5b2abe0SLewanczyk, Dawid             }
5971e1e598dSJonathan Doman         });
598c5b2abe0SLewanczyk, Dawid }
599c5b2abe0SLewanczyk, Dawid 
600c5b2abe0SLewanczyk, Dawid /**
601786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
602491d8ee7SSantosh Puranik  *
603491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
604491d8ee7SSantosh Puranik  *
605491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
606491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
607491d8ee7SSantosh Puranik  */
60823a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
609491d8ee7SSantosh Puranik {
610491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
611491d8ee7SSantosh Puranik     {
612491d8ee7SSantosh Puranik         return "None";
613491d8ee7SSantosh Puranik     }
6143174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
615491d8ee7SSantosh Puranik     {
616491d8ee7SSantosh Puranik         return "Hdd";
617491d8ee7SSantosh Puranik     }
6183174e4dfSEd Tanous     if (dbusSource ==
619a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
620491d8ee7SSantosh Puranik     {
621491d8ee7SSantosh Puranik         return "Cd";
622491d8ee7SSantosh Puranik     }
6233174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
624491d8ee7SSantosh Puranik     {
625491d8ee7SSantosh Puranik         return "Pxe";
626491d8ee7SSantosh Puranik     }
6273174e4dfSEd Tanous     if (dbusSource ==
628944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6299f16b2c1SJennifer Lee     {
6309f16b2c1SJennifer Lee         return "Usb";
6319f16b2c1SJennifer Lee     }
632491d8ee7SSantosh Puranik     return "";
633491d8ee7SSantosh Puranik }
634491d8ee7SSantosh Puranik 
635491d8ee7SSantosh Puranik /**
636cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
637cd9a4666SKonstantin Aladyshev  *
638cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
639cd9a4666SKonstantin Aladyshev  *
640cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
641cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
642cd9a4666SKonstantin Aladyshev  */
643cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
644cd9a4666SKonstantin Aladyshev {
645cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
646cd9a4666SKonstantin Aladyshev     {
647cd9a4666SKonstantin Aladyshev         return "Legacy";
648cd9a4666SKonstantin Aladyshev     }
649cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
650cd9a4666SKonstantin Aladyshev     {
651cd9a4666SKonstantin Aladyshev         return "UEFI";
652cd9a4666SKonstantin Aladyshev     }
653cd9a4666SKonstantin Aladyshev     return "";
654cd9a4666SKonstantin Aladyshev }
655cd9a4666SKonstantin Aladyshev 
656cd9a4666SKonstantin Aladyshev /**
657786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
658491d8ee7SSantosh Puranik  *
659491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
660491d8ee7SSantosh Puranik  *
661491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
662491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
663491d8ee7SSantosh Puranik  */
66423a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
665491d8ee7SSantosh Puranik {
666491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
667491d8ee7SSantosh Puranik     {
668491d8ee7SSantosh Puranik         return "None";
669491d8ee7SSantosh Puranik     }
6703174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
671491d8ee7SSantosh Puranik     {
672491d8ee7SSantosh Puranik         return "Diags";
673491d8ee7SSantosh Puranik     }
6743174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
675491d8ee7SSantosh Puranik     {
676491d8ee7SSantosh Puranik         return "BiosSetup";
677491d8ee7SSantosh Puranik     }
678491d8ee7SSantosh Puranik     return "";
679491d8ee7SSantosh Puranik }
680491d8ee7SSantosh Puranik 
681491d8ee7SSantosh Puranik /**
682e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
683e43914b3SAndrew Geissler  *
684e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
685e43914b3SAndrew Geissler  *
686e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
687e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
688e43914b3SAndrew Geissler  */
689e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
690e43914b3SAndrew Geissler {
691e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
692e43914b3SAndrew Geissler     // enum
693e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
694e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
695e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
696e43914b3SAndrew Geissler     {
697e43914b3SAndrew Geissler         rfBpLastState = "None";
698e43914b3SAndrew Geissler     }
699e43914b3SAndrew Geissler     else if (dbusBootProgress ==
700e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
701e43914b3SAndrew Geissler              "PrimaryProcInit")
702e43914b3SAndrew Geissler     {
703e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
704e43914b3SAndrew Geissler     }
705e43914b3SAndrew Geissler     else if (dbusBootProgress ==
706e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
707e43914b3SAndrew Geissler              "BusInit")
708e43914b3SAndrew Geissler     {
709e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
710e43914b3SAndrew Geissler     }
711e43914b3SAndrew Geissler     else if (dbusBootProgress ==
712e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
713e43914b3SAndrew Geissler              "MemoryInit")
714e43914b3SAndrew Geissler     {
715e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
716e43914b3SAndrew Geissler     }
717e43914b3SAndrew Geissler     else if (dbusBootProgress ==
718e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
719e43914b3SAndrew Geissler              "SecondaryProcInit")
720e43914b3SAndrew Geissler     {
721e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
722e43914b3SAndrew Geissler     }
723e43914b3SAndrew Geissler     else if (dbusBootProgress ==
724e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
725e43914b3SAndrew Geissler              "PCIInit")
726e43914b3SAndrew Geissler     {
727e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
728e43914b3SAndrew Geissler     }
729e43914b3SAndrew Geissler     else if (dbusBootProgress ==
730e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
731e43914b3SAndrew Geissler              "SystemSetup")
732e43914b3SAndrew Geissler     {
733e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
734e43914b3SAndrew Geissler     }
735e43914b3SAndrew Geissler     else if (dbusBootProgress ==
736e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
737e43914b3SAndrew Geissler              "SystemInitComplete")
738e43914b3SAndrew Geissler     {
739e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
740e43914b3SAndrew Geissler     }
741e43914b3SAndrew Geissler     else if (dbusBootProgress ==
742e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
743e43914b3SAndrew Geissler              "OSStart")
744e43914b3SAndrew Geissler     {
745e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
746e43914b3SAndrew Geissler     }
747e43914b3SAndrew Geissler     else if (dbusBootProgress ==
748e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
749e43914b3SAndrew Geissler              "OSRunning")
750e43914b3SAndrew Geissler     {
751e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
752e43914b3SAndrew Geissler     }
753e43914b3SAndrew Geissler     else
754e43914b3SAndrew Geissler     {
755e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
756e43914b3SAndrew Geissler                          << dbusBootProgress;
757e43914b3SAndrew Geissler         // Just return the default
758e43914b3SAndrew Geissler     }
759e43914b3SAndrew Geissler     return rfBpLastState;
760e43914b3SAndrew Geissler }
761e43914b3SAndrew Geissler 
762e43914b3SAndrew Geissler /**
763786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
764491d8ee7SSantosh Puranik  *
765491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
766944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
767944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
768491d8ee7SSantosh Puranik  *
769944ffaf9SJohnathan Mantey  * @return Integer error code.
770491d8ee7SSantosh Puranik  */
7718d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
772944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
773944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
774491d8ee7SSantosh Puranik {
775c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
776c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
777944ffaf9SJohnathan Mantey 
778491d8ee7SSantosh Puranik     if (rfSource == "None")
779491d8ee7SSantosh Puranik     {
780944ffaf9SJohnathan Mantey         return 0;
781491d8ee7SSantosh Puranik     }
7823174e4dfSEd Tanous     if (rfSource == "Pxe")
783491d8ee7SSantosh Puranik     {
784944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
785944ffaf9SJohnathan Mantey     }
786944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
787944ffaf9SJohnathan Mantey     {
788944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
789944ffaf9SJohnathan Mantey     }
790944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
791944ffaf9SJohnathan Mantey     {
792944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
793944ffaf9SJohnathan Mantey     }
794944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
795944ffaf9SJohnathan Mantey     {
796944ffaf9SJohnathan Mantey         bootSource =
797944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
798944ffaf9SJohnathan Mantey     }
799944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
800944ffaf9SJohnathan Mantey     {
801944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
802491d8ee7SSantosh Puranik     }
8039f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8049f16b2c1SJennifer Lee     {
805944ffaf9SJohnathan Mantey         bootSource =
806944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8079f16b2c1SJennifer Lee     }
808491d8ee7SSantosh Puranik     else
809491d8ee7SSantosh Puranik     {
8100fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8110fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
812944ffaf9SJohnathan Mantey             << bootSource;
813944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
814944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
815944ffaf9SJohnathan Mantey         return -1;
816491d8ee7SSantosh Puranik     }
817944ffaf9SJohnathan Mantey     return 0;
818491d8ee7SSantosh Puranik }
8191981771bSAli Ahmed 
820978b8803SAndrew Geissler /**
821978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
822978b8803SAndrew Geissler  *
823978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
824978b8803SAndrew Geissler  *
825978b8803SAndrew Geissler  * @return None.
826978b8803SAndrew Geissler  */
8278d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
828978b8803SAndrew Geissler {
8291e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8301e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8311e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8321e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
833978b8803SAndrew Geissler         [aResp](const boost::system::error_code ec,
8341e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
835978b8803SAndrew Geissler             if (ec)
836978b8803SAndrew Geissler             {
837978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
838978b8803SAndrew Geissler                 // not found
839978b8803SAndrew Geissler                 return;
840978b8803SAndrew Geissler             }
841978b8803SAndrew Geissler 
8421e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
843978b8803SAndrew Geissler 
844e43914b3SAndrew Geissler             aResp->res.jsonValue["BootProgress"]["LastState"] =
845e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
8461e1e598dSJonathan Doman         });
847978b8803SAndrew Geissler }
848491d8ee7SSantosh Puranik 
849491d8ee7SSantosh Puranik /**
850c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
851cd9a4666SKonstantin Aladyshev  *
852cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
853cd9a4666SKonstantin Aladyshev  *
854cd9a4666SKonstantin Aladyshev  * @return None.
855cd9a4666SKonstantin Aladyshev  */
856cd9a4666SKonstantin Aladyshev 
857c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
858cd9a4666SKonstantin Aladyshev {
8591e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8601e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
8611e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8621e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
863cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
8641e1e598dSJonathan Doman                 const std::string& bootType) {
865cd9a4666SKonstantin Aladyshev             if (ec)
866cd9a4666SKonstantin Aladyshev             {
867cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
868cd9a4666SKonstantin Aladyshev                 return;
869cd9a4666SKonstantin Aladyshev             }
870cd9a4666SKonstantin Aladyshev 
8711e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
872cd9a4666SKonstantin Aladyshev 
8730fda0f12SGeorge Liu             aResp->res
8740fda0f12SGeorge Liu                 .jsonValue["Boot"]
8750fda0f12SGeorge Liu                           ["BootSourceOverrideMode@Redfish.AllowableValues"] = {
8760fda0f12SGeorge Liu                 "Legacy", "UEFI"};
877cd9a4666SKonstantin Aladyshev 
8781e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
879cd9a4666SKonstantin Aladyshev             if (rfType.empty())
880cd9a4666SKonstantin Aladyshev             {
881cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
882cd9a4666SKonstantin Aladyshev                 return;
883cd9a4666SKonstantin Aladyshev             }
884cd9a4666SKonstantin Aladyshev 
885cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
8861e1e598dSJonathan Doman         });
887cd9a4666SKonstantin Aladyshev }
888cd9a4666SKonstantin Aladyshev 
889cd9a4666SKonstantin Aladyshev /**
890c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
891491d8ee7SSantosh Puranik  *
892491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
893491d8ee7SSantosh Puranik  *
894491d8ee7SSantosh Puranik  * @return None.
895491d8ee7SSantosh Puranik  */
896c21865c4SKonstantin Aladyshev 
897c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
898491d8ee7SSantosh Puranik {
8991e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9001e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9011e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9021e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
903c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
9041e1e598dSJonathan Doman                 const std::string& bootModeStr) {
905491d8ee7SSantosh Puranik             if (ec)
906491d8ee7SSantosh Puranik             {
907491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
908491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
909491d8ee7SSantosh Puranik                 return;
910491d8ee7SSantosh Puranik             }
911491d8ee7SSantosh Puranik 
9121e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
913491d8ee7SSantosh Puranik 
9140fda0f12SGeorge Liu             aResp->res
9150fda0f12SGeorge Liu                 .jsonValue["Boot"]
9160fda0f12SGeorge Liu                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
9170fda0f12SGeorge Liu                 {"None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
918491d8ee7SSantosh Puranik 
9191e1e598dSJonathan Doman             if (bootModeStr !=
920491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
921491d8ee7SSantosh Puranik             {
9221e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
923491d8ee7SSantosh Puranik                 if (!rfMode.empty())
924491d8ee7SSantosh Puranik                 {
925491d8ee7SSantosh Puranik                     aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
926491d8ee7SSantosh Puranik                         rfMode;
927491d8ee7SSantosh Puranik                 }
928491d8ee7SSantosh Puranik             }
9291e1e598dSJonathan Doman         });
930491d8ee7SSantosh Puranik }
931491d8ee7SSantosh Puranik 
932491d8ee7SSantosh Puranik /**
933c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
934491d8ee7SSantosh Puranik  *
935491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
936491d8ee7SSantosh Puranik  *
937491d8ee7SSantosh Puranik  * @return None.
938491d8ee7SSantosh Puranik  */
939c21865c4SKonstantin Aladyshev 
940c21865c4SKonstantin Aladyshev inline void
941c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
942491d8ee7SSantosh Puranik {
9431e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9441e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9451e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9461e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
947c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
9481e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
949491d8ee7SSantosh Puranik             if (ec)
950491d8ee7SSantosh Puranik             {
951491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
952491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
953491d8ee7SSantosh Puranik                 return;
954491d8ee7SSantosh Puranik             }
955491d8ee7SSantosh Puranik 
9561e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
957491d8ee7SSantosh Puranik 
9581e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
959491d8ee7SSantosh Puranik             if (!rfSource.empty())
960491d8ee7SSantosh Puranik             {
961491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
962491d8ee7SSantosh Puranik                     rfSource;
963491d8ee7SSantosh Puranik             }
964cd9a4666SKonstantin Aladyshev 
965cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
966cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
967c21865c4SKonstantin Aladyshev             getBootOverrideMode(aResp);
9681e1e598dSJonathan Doman         });
969491d8ee7SSantosh Puranik }
970491d8ee7SSantosh Puranik 
971491d8ee7SSantosh Puranik /**
972c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
973c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
974c21865c4SKonstantin Aladyshev  * state
975491d8ee7SSantosh Puranik  *
976491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
977491d8ee7SSantosh Puranik  *
978491d8ee7SSantosh Puranik  * @return None.
979491d8ee7SSantosh Puranik  */
980491d8ee7SSantosh Puranik 
981c21865c4SKonstantin Aladyshev inline void
982c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
983c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
984c21865c4SKonstantin Aladyshev {
985c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
986c21865c4SKonstantin Aladyshev     {
987c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
988c21865c4SKonstantin Aladyshev         return;
989c21865c4SKonstantin Aladyshev     }
990c21865c4SKonstantin Aladyshev 
991c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
992c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
9931e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
9941e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9951e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
9961e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
9971e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
998491d8ee7SSantosh Puranik             if (ec)
999491d8ee7SSantosh Puranik             {
1000491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1001c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1002491d8ee7SSantosh Puranik                 return;
1003491d8ee7SSantosh Puranik             }
1004491d8ee7SSantosh Puranik 
1005c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1006c21865c4SKonstantin Aladyshev             {
1007c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1008c21865c4SKonstantin Aladyshev                     "Once";
1009c21865c4SKonstantin Aladyshev             }
1010c21865c4SKonstantin Aladyshev             else
1011c21865c4SKonstantin Aladyshev             {
1012c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1013c21865c4SKonstantin Aladyshev                     "Continuous";
1014c21865c4SKonstantin Aladyshev             }
10151e1e598dSJonathan Doman         });
1016491d8ee7SSantosh Puranik }
1017491d8ee7SSantosh Puranik 
1018491d8ee7SSantosh Puranik /**
1019c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1020c21865c4SKonstantin Aladyshev  *
1021c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1022c21865c4SKonstantin Aladyshev  *
1023c21865c4SKonstantin Aladyshev  * @return None.
1024c21865c4SKonstantin Aladyshev  */
1025c21865c4SKonstantin Aladyshev 
1026c21865c4SKonstantin Aladyshev inline void
1027c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1028c21865c4SKonstantin Aladyshev {
10291e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10301e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10311e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10321e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1033c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
10341e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1035c21865c4SKonstantin Aladyshev             if (ec)
1036c21865c4SKonstantin Aladyshev             {
1037c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1038c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1039c21865c4SKonstantin Aladyshev                 return;
1040c21865c4SKonstantin Aladyshev             }
1041c21865c4SKonstantin Aladyshev 
10421e1e598dSJonathan Doman             processBootOverrideEnable(aResp, bootOverrideEnable);
10431e1e598dSJonathan Doman         });
1044c21865c4SKonstantin Aladyshev }
1045c21865c4SKonstantin Aladyshev 
1046c21865c4SKonstantin Aladyshev /**
1047c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1048c21865c4SKonstantin Aladyshev  *
1049c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1050c21865c4SKonstantin Aladyshev  *
1051c21865c4SKonstantin Aladyshev  * @return None.
1052c21865c4SKonstantin Aladyshev  */
1053c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1054c21865c4SKonstantin Aladyshev {
1055c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1056c21865c4SKonstantin Aladyshev 
1057c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1058c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1059c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1060c21865c4SKonstantin Aladyshev }
1061c21865c4SKonstantin Aladyshev 
1062c21865c4SKonstantin Aladyshev /**
1063c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1064c0557e1aSGunnar Mills  *
1065c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1066c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1067c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1068c0557e1aSGunnar Mills  * last power operation time.
1069c0557e1aSGunnar Mills  *
1070c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1071c0557e1aSGunnar Mills  *
1072c0557e1aSGunnar Mills  * @return None.
1073c0557e1aSGunnar Mills  */
10748d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1075c0557e1aSGunnar Mills {
1076c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1077c0557e1aSGunnar Mills 
10781e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
10791e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
10801e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
10811e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
10821e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
1083c0557e1aSGunnar Mills             if (ec)
1084c0557e1aSGunnar Mills             {
1085c0557e1aSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1086c0557e1aSGunnar Mills                 return;
1087c0557e1aSGunnar Mills             }
1088c0557e1aSGunnar Mills 
1089c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1090c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
10911e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1092c0557e1aSGunnar Mills 
1093c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1094c0557e1aSGunnar Mills             aResp->res.jsonValue["LastResetTime"] =
10951d8782e7SNan Zhou                 crow::utility::getDateTimeUint(lastResetTimeStamp);
10961e1e598dSJonathan Doman         });
1097c0557e1aSGunnar Mills }
1098c0557e1aSGunnar Mills 
1099c0557e1aSGunnar Mills /**
11006bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11016bd5a8d2SGunnar Mills  *
11026bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11036bd5a8d2SGunnar Mills  *
11046bd5a8d2SGunnar Mills  * @return None.
11056bd5a8d2SGunnar Mills  */
11068d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11076bd5a8d2SGunnar Mills {
11086bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
11096bd5a8d2SGunnar Mills 
11101e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11111e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11121e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
11131e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
11141e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
11156bd5a8d2SGunnar Mills             if (ec)
11166bd5a8d2SGunnar Mills             {
11176bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
11186bd5a8d2SGunnar Mills                 return;
11196bd5a8d2SGunnar Mills             }
11206bd5a8d2SGunnar Mills 
11211e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1122e05aec50SEd Tanous             if (autoRebootEnabled)
11236bd5a8d2SGunnar Mills             {
11246bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11256bd5a8d2SGunnar Mills                     "RetryAttempts";
11266bd5a8d2SGunnar Mills                 // If AutomaticRetry (AutoReboot) is enabled see how many
11276bd5a8d2SGunnar Mills                 // attempts are left
11281e1e598dSJonathan Doman                 sdbusplus::asio::getProperty<uint32_t>(
11291e1e598dSJonathan Doman                     *crow::connections::systemBus,
11301e1e598dSJonathan Doman                     "xyz.openbmc_project.State.Host",
11311e1e598dSJonathan Doman                     "/xyz/openbmc_project/state/host0",
11321e1e598dSJonathan Doman                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
11331e1e598dSJonathan Doman                     "AttemptsLeft",
1134cb13a392SEd Tanous                     [aResp](const boost::system::error_code ec2,
1135914e2d5dSEd Tanous                             const uint32_t autoRebootAttemptsLeft) {
1136cb13a392SEd Tanous                         if (ec2)
11376bd5a8d2SGunnar Mills                         {
1138cb13a392SEd Tanous                             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
11396bd5a8d2SGunnar Mills                             return;
11406bd5a8d2SGunnar Mills                         }
11416bd5a8d2SGunnar Mills 
11426bd5a8d2SGunnar Mills                         BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
11431e1e598dSJonathan Doman                                          << autoRebootAttemptsLeft;
11446bd5a8d2SGunnar Mills 
11456bd5a8d2SGunnar Mills                         aResp->res
11466bd5a8d2SGunnar Mills                             .jsonValue["Boot"]
11476bd5a8d2SGunnar Mills                                       ["RemainingAutomaticRetryAttempts"] =
11481e1e598dSJonathan Doman                             autoRebootAttemptsLeft;
11491e1e598dSJonathan Doman                     });
11506bd5a8d2SGunnar Mills             }
11516bd5a8d2SGunnar Mills             else
11526bd5a8d2SGunnar Mills             {
11536bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11546bd5a8d2SGunnar Mills                     "Disabled";
11556bd5a8d2SGunnar Mills             }
11566bd5a8d2SGunnar Mills 
11576bd5a8d2SGunnar Mills             // Not on D-Bus. Hardcoded here:
11586bd5a8d2SGunnar Mills             // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
11596bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
116069f35306SGunnar Mills 
116169f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
116269f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
116369f35306SGunnar Mills             // RetryAttempts.
11640fda0f12SGeorge Liu             aResp->res
11650fda0f12SGeorge Liu                 .jsonValue["Boot"]
11660fda0f12SGeorge Liu                           ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
11670fda0f12SGeorge Liu                 "Disabled", "RetryAttempts"};
11681e1e598dSJonathan Doman         });
11696bd5a8d2SGunnar Mills }
11706bd5a8d2SGunnar Mills 
11716bd5a8d2SGunnar Mills /**
1172c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1173c6a620f2SGeorge Liu  *
1174c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1175c6a620f2SGeorge Liu  *
1176c6a620f2SGeorge Liu  * @return None.
1177c6a620f2SGeorge Liu  */
11788d1b46d7Szhanghch05 inline void
11798d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1180c6a620f2SGeorge Liu {
1181c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1182c6a620f2SGeorge Liu 
11831e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
11841e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11851e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
11861e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
11871e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, const std::string& policy) {
1188c6a620f2SGeorge Liu             if (ec)
1189c6a620f2SGeorge Liu             {
1190c6a620f2SGeorge Liu                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1191c6a620f2SGeorge Liu                 return;
1192c6a620f2SGeorge Liu             }
1193c6a620f2SGeorge Liu 
11940fda0f12SGeorge Liu             const boost::container::flat_map<std::string, std::string> policyMaps = {
11950fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1196c6a620f2SGeorge Liu                  "AlwaysOn"},
11970fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1198c6a620f2SGeorge Liu                  "AlwaysOff"},
11990fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
12004ed47cb8SMatthew Barth                  "LastState"},
12014ed47cb8SMatthew Barth                 // Return `AlwaysOff` when power restore policy set to "None"
12024ed47cb8SMatthew Barth                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
12034ed47cb8SMatthew Barth                  "AlwaysOff"}};
1204c6a620f2SGeorge Liu 
12051e1e598dSJonathan Doman             auto policyMapsIt = policyMaps.find(policy);
1206c6a620f2SGeorge Liu             if (policyMapsIt == policyMaps.end())
1207c6a620f2SGeorge Liu             {
1208c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1209c6a620f2SGeorge Liu                 return;
1210c6a620f2SGeorge Liu             }
1211c6a620f2SGeorge Liu 
1212c6a620f2SGeorge Liu             aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
12131e1e598dSJonathan Doman         });
1214c6a620f2SGeorge Liu }
1215c6a620f2SGeorge Liu 
1216c6a620f2SGeorge Liu /**
12171981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
12181981771bSAli Ahmed  * TPM is required for booting the host.
12191981771bSAli Ahmed  *
12201981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
12211981771bSAli Ahmed  *
12221981771bSAli Ahmed  * @return None.
12231981771bSAli Ahmed  */
12241981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
12251981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12261981771bSAli Ahmed {
12271981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
12281981771bSAli Ahmed 
12291981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
1230b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
1231b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
12321981771bSAli Ahmed             if (ec)
12331981771bSAli Ahmed             {
12341981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
12351981771bSAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
12361981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
12371981771bSAli Ahmed                 // error occurs
12381981771bSAli Ahmed                 return;
12391981771bSAli Ahmed             }
124026f6976fSEd Tanous             if (subtree.empty())
12411981771bSAli Ahmed             {
12421981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
12431981771bSAli Ahmed                 // if there is no instance found
12441981771bSAli Ahmed                 return;
12451981771bSAli Ahmed             }
12461981771bSAli Ahmed 
12471981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
12481981771bSAli Ahmed             if (subtree.size() > 1)
12491981771bSAli Ahmed             {
12501981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
12511981771bSAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
12521981771bSAli Ahmed                     << subtree.size();
12531981771bSAli Ahmed                 // Throw an internal Error and return
12541981771bSAli Ahmed                 messages::internalError(aResp->res);
12551981771bSAli Ahmed                 return;
12561981771bSAli Ahmed             }
12571981771bSAli Ahmed 
12581981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
12591981771bSAli Ahmed             // field
12601981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
12611981771bSAli Ahmed             {
12621981771bSAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
12631981771bSAli Ahmed                 messages::internalError(aResp->res);
12641981771bSAli Ahmed                 return;
12651981771bSAli Ahmed             }
12661981771bSAli Ahmed 
12671981771bSAli Ahmed             const std::string& path = subtree[0].first;
12681981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
12691981771bSAli Ahmed 
12701981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
12711e1e598dSJonathan Doman             sdbusplus::asio::getProperty<bool>(
12721e1e598dSJonathan Doman                 *crow::connections::systemBus, serv, path,
12731e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
12741e1e598dSJonathan Doman                 [aResp](const boost::system::error_code ec, bool tpmRequired) {
12751981771bSAli Ahmed                     if (ec)
12761981771bSAli Ahmed                     {
12771981771bSAli Ahmed                         BMCWEB_LOG_DEBUG
12781981771bSAli Ahmed                             << "D-BUS response error on TPM.Policy Get" << ec;
12791981771bSAli Ahmed                         messages::internalError(aResp->res);
12801981771bSAli Ahmed                         return;
12811981771bSAli Ahmed                     }
12821981771bSAli Ahmed 
12831e1e598dSJonathan Doman                     if (tpmRequired)
12841981771bSAli Ahmed                     {
12851981771bSAli Ahmed                         aResp->res
12861981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
12871981771bSAli Ahmed                             "Required";
12881981771bSAli Ahmed                     }
12891981771bSAli Ahmed                     else
12901981771bSAli Ahmed                     {
12911981771bSAli Ahmed                         aResp->res
12921981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
12931981771bSAli Ahmed                             "Disabled";
12941981771bSAli Ahmed                     }
12951e1e598dSJonathan Doman                 });
12961981771bSAli Ahmed         },
12971981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
12981981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
12991981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
13001981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
13011981771bSAli Ahmed }
13021981771bSAli Ahmed 
13031981771bSAli Ahmed /**
13041c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
13051c05dae3SAli Ahmed  * TPM is required for booting the host.
13061c05dae3SAli Ahmed  *
13071c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
13081c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
13091c05dae3SAli Ahmed  *
13101c05dae3SAli Ahmed  * @return None.
13111c05dae3SAli Ahmed  */
13121c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
13131c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
13141c05dae3SAli Ahmed {
13151c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
13161c05dae3SAli Ahmed 
13171c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
1318b9d36b47SEd Tanous         [aResp, tpmRequired](const boost::system::error_code ec,
1319b9d36b47SEd Tanous                              dbus::utility::MapperGetSubTreeResponse& subtree) {
13201c05dae3SAli Ahmed             if (ec)
13211c05dae3SAli Ahmed             {
13221c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
13231c05dae3SAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
13241c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13251c05dae3SAli Ahmed                 return;
13261c05dae3SAli Ahmed             }
132726f6976fSEd Tanous             if (subtree.empty())
13281c05dae3SAli Ahmed             {
13291c05dae3SAli Ahmed                 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
13301c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
13311c05dae3SAli Ahmed                 return;
13321c05dae3SAli Ahmed             }
13331c05dae3SAli Ahmed 
13341c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
13351c05dae3SAli Ahmed             if (subtree.size() > 1)
13361c05dae3SAli Ahmed             {
13371c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
13381c05dae3SAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
13391c05dae3SAli Ahmed                     << subtree.size();
13401c05dae3SAli Ahmed                 // Throw an internal Error and return
13411c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13421c05dae3SAli Ahmed                 return;
13431c05dae3SAli Ahmed             }
13441c05dae3SAli Ahmed 
13451c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
13461c05dae3SAli Ahmed             // field
13471c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13481c05dae3SAli Ahmed             {
13491c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13501c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13511c05dae3SAli Ahmed                 return;
13521c05dae3SAli Ahmed             }
13531c05dae3SAli Ahmed 
13541c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
13551c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
13561c05dae3SAli Ahmed 
13571c05dae3SAli Ahmed             if (serv.empty())
13581c05dae3SAli Ahmed             {
13591c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
13601c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13611c05dae3SAli Ahmed                 return;
13621c05dae3SAli Ahmed             }
13631c05dae3SAli Ahmed 
13641c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
13651c05dae3SAli Ahmed             crow::connections::systemBus->async_method_call(
13661c05dae3SAli Ahmed                 [aResp](const boost::system::error_code ec) {
13671c05dae3SAli Ahmed                     if (ec)
13681c05dae3SAli Ahmed                     {
13690fda0f12SGeorge Liu                         BMCWEB_LOG_DEBUG
13700fda0f12SGeorge Liu                             << "DBUS response error: Set TrustedModuleRequiredToBoot"
13711c05dae3SAli Ahmed                             << ec;
13721c05dae3SAli Ahmed                         messages::internalError(aResp->res);
13731c05dae3SAli Ahmed                         return;
13741c05dae3SAli Ahmed                     }
13751c05dae3SAli Ahmed                     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
13761c05dae3SAli Ahmed                 },
13771c05dae3SAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Set",
13781c05dae3SAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1379168e20c1SEd Tanous                 dbus::utility::DbusVariantType(tpmRequired));
13801c05dae3SAli Ahmed         },
13811c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
13821c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
13831c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
13841c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
13851c05dae3SAli Ahmed }
13861c05dae3SAli Ahmed 
13871c05dae3SAli Ahmed /**
1388491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1389491d8ee7SSantosh Puranik  *
1390491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1391cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1392cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1393cd9a4666SKonstantin Aladyshev  */
1394cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1395cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1396cd9a4666SKonstantin Aladyshev {
1397c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1398cd9a4666SKonstantin Aladyshev 
1399c21865c4SKonstantin Aladyshev     if (!bootType)
1400cd9a4666SKonstantin Aladyshev     {
1401c21865c4SKonstantin Aladyshev         return;
1402c21865c4SKonstantin Aladyshev     }
1403c21865c4SKonstantin Aladyshev 
1404cd9a4666SKonstantin Aladyshev     // Source target specified
1405cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1406cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1407cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1408cd9a4666SKonstantin Aladyshev     {
1409cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1410cd9a4666SKonstantin Aladyshev     }
1411cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1412cd9a4666SKonstantin Aladyshev     {
1413cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1414cd9a4666SKonstantin Aladyshev     }
1415cd9a4666SKonstantin Aladyshev     else
1416cd9a4666SKonstantin Aladyshev     {
1417cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1418cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1419cd9a4666SKonstantin Aladyshev                          << *bootType;
1420cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1421cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1422cd9a4666SKonstantin Aladyshev         return;
1423cd9a4666SKonstantin Aladyshev     }
1424cd9a4666SKonstantin Aladyshev 
1425cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1426cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1427cd9a4666SKonstantin Aladyshev 
1428cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1429c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1430cd9a4666SKonstantin Aladyshev             if (ec)
1431cd9a4666SKonstantin Aladyshev             {
1432cd9a4666SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1433cd9a4666SKonstantin Aladyshev                 if (ec.value() == boost::asio::error::host_unreachable)
1434cd9a4666SKonstantin Aladyshev                 {
1435cd9a4666SKonstantin Aladyshev                     messages::resourceNotFound(aResp->res, "Set", "BootType");
1436cd9a4666SKonstantin Aladyshev                     return;
1437cd9a4666SKonstantin Aladyshev                 }
1438cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
1439cd9a4666SKonstantin Aladyshev                 return;
1440cd9a4666SKonstantin Aladyshev             }
1441cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type update done.";
1442cd9a4666SKonstantin Aladyshev         },
1443c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1444c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1445cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1446cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1447168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1448cd9a4666SKonstantin Aladyshev }
1449cd9a4666SKonstantin Aladyshev 
1450cd9a4666SKonstantin Aladyshev /**
1451cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1452cd9a4666SKonstantin Aladyshev  *
1453cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1454c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1455c21865c4SKonstantin Aladyshev  * @return Integer error code.
1456c21865c4SKonstantin Aladyshev  */
1457c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1458c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1459c21865c4SKonstantin Aladyshev {
1460c21865c4SKonstantin Aladyshev     if (!bootEnable)
1461c21865c4SKonstantin Aladyshev     {
1462c21865c4SKonstantin Aladyshev         return;
1463c21865c4SKonstantin Aladyshev     }
1464c21865c4SKonstantin Aladyshev     // Source target specified
1465c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1466c21865c4SKonstantin Aladyshev 
1467c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1468c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1469c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1470c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1471c21865c4SKonstantin Aladyshev     {
1472c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1473c21865c4SKonstantin Aladyshev     }
1474c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1475c21865c4SKonstantin Aladyshev     {
1476c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1477c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1478c21865c4SKonstantin Aladyshev     }
1479c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1480c21865c4SKonstantin Aladyshev     {
1481c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1482c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1483c21865c4SKonstantin Aladyshev     }
1484c21865c4SKonstantin Aladyshev     else
1485c21865c4SKonstantin Aladyshev     {
14860fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
14870fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1488c21865c4SKonstantin Aladyshev             << *bootEnable;
1489c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1490c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1491c21865c4SKonstantin Aladyshev         return;
1492c21865c4SKonstantin Aladyshev     }
1493c21865c4SKonstantin Aladyshev 
1494c21865c4SKonstantin Aladyshev     // Act on validated parameters
1495c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1496c21865c4SKonstantin Aladyshev 
1497c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1498c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1499c21865c4SKonstantin Aladyshev             if (ec)
1500c21865c4SKonstantin Aladyshev             {
1501c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1502c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1503c21865c4SKonstantin Aladyshev                 return;
1504c21865c4SKonstantin Aladyshev             }
1505c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1506c21865c4SKonstantin Aladyshev         },
1507c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1508c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1509c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1510c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1511168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1512c21865c4SKonstantin Aladyshev 
1513c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1514c21865c4SKonstantin Aladyshev     {
1515c21865c4SKonstantin Aladyshev         return;
1516c21865c4SKonstantin Aladyshev     }
1517c21865c4SKonstantin Aladyshev 
1518c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1519c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1520c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1521c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1522c21865c4SKonstantin Aladyshev 
1523c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1524c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1525c21865c4SKonstantin Aladyshev             if (ec)
1526c21865c4SKonstantin Aladyshev             {
1527c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1528c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1529c21865c4SKonstantin Aladyshev                 return;
1530c21865c4SKonstantin Aladyshev             }
1531c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1532c21865c4SKonstantin Aladyshev         },
1533c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1534c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1535c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1536c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1537168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1538c21865c4SKonstantin Aladyshev }
1539c21865c4SKonstantin Aladyshev 
1540c21865c4SKonstantin Aladyshev /**
1541c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1542c21865c4SKonstantin Aladyshev  *
1543c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1544491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1545491d8ee7SSantosh Puranik  *
1546265c1602SJohnathan Mantey  * @return Integer error code.
1547491d8ee7SSantosh Puranik  */
1548cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1549cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1550491d8ee7SSantosh Puranik {
1551c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1552c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1553944ffaf9SJohnathan Mantey 
1554c21865c4SKonstantin Aladyshev     if (!bootSource)
1555491d8ee7SSantosh Puranik     {
1556c21865c4SKonstantin Aladyshev         return;
1557c21865c4SKonstantin Aladyshev     }
1558c21865c4SKonstantin Aladyshev 
1559491d8ee7SSantosh Puranik     // Source target specified
1560491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1561491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1562e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1563e662eae8SEd Tanous         0)
1564491d8ee7SSantosh Puranik     {
1565944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1566944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1567491d8ee7SSantosh Puranik             << *bootSource;
1568491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1569491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1570491d8ee7SSantosh Puranik         return;
1571491d8ee7SSantosh Puranik     }
1572491d8ee7SSantosh Puranik 
1573944ffaf9SJohnathan Mantey     // Act on validated parameters
1574944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1575944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1576944ffaf9SJohnathan Mantey 
1577491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1578491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1579491d8ee7SSantosh Puranik             if (ec)
1580491d8ee7SSantosh Puranik             {
1581491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1582491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1583491d8ee7SSantosh Puranik                 return;
1584491d8ee7SSantosh Puranik             }
1585491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source update done.";
1586491d8ee7SSantosh Puranik         },
1587c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1588c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1589491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1590491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1591168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1592944ffaf9SJohnathan Mantey 
1593491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1594491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1595491d8ee7SSantosh Puranik             if (ec)
1596491d8ee7SSantosh Puranik             {
1597491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1598491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1599491d8ee7SSantosh Puranik                 return;
1600491d8ee7SSantosh Puranik             }
1601491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode update done.";
1602491d8ee7SSantosh Puranik         },
1603c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1604c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1605491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1606491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1607168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1608cd9a4666SKonstantin Aladyshev }
1609944ffaf9SJohnathan Mantey 
1610cd9a4666SKonstantin Aladyshev /**
1611c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1612491d8ee7SSantosh Puranik  *
1613491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1614491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1615cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1616491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1617491d8ee7SSantosh Puranik  *
1618265c1602SJohnathan Mantey  * @return Integer error code.
1619491d8ee7SSantosh Puranik  */
1620c21865c4SKonstantin Aladyshev 
1621c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1622c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1623c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1624c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1625491d8ee7SSantosh Puranik {
1626491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1627491d8ee7SSantosh Puranik 
1628c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1629c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1630c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1631491d8ee7SSantosh Puranik }
1632491d8ee7SSantosh Puranik 
1633c6a620f2SGeorge Liu /**
163498e386ecSGunnar Mills  * @brief Sets AssetTag
163598e386ecSGunnar Mills  *
163698e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
163798e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
163898e386ecSGunnar Mills  *
163998e386ecSGunnar Mills  * @return None.
164098e386ecSGunnar Mills  */
16418d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
164298e386ecSGunnar Mills                         const std::string& assetTag)
164398e386ecSGunnar Mills {
164498e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
1645b9d36b47SEd Tanous         [aResp,
1646b9d36b47SEd Tanous          assetTag](const boost::system::error_code ec,
1647b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
164898e386ecSGunnar Mills             if (ec)
164998e386ecSGunnar Mills             {
165098e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
165198e386ecSGunnar Mills                 messages::internalError(aResp->res);
165298e386ecSGunnar Mills                 return;
165398e386ecSGunnar Mills             }
165426f6976fSEd Tanous             if (subtree.empty())
165598e386ecSGunnar Mills             {
165698e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
165798e386ecSGunnar Mills                 messages::internalError(aResp->res);
165898e386ecSGunnar Mills                 return;
165998e386ecSGunnar Mills             }
166098e386ecSGunnar Mills             // Assume only 1 system D-Bus object
166198e386ecSGunnar Mills             // Throw an error if there is more than 1
166298e386ecSGunnar Mills             if (subtree.size() > 1)
166398e386ecSGunnar Mills             {
166498e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
166598e386ecSGunnar Mills                 messages::internalError(aResp->res);
166698e386ecSGunnar Mills                 return;
166798e386ecSGunnar Mills             }
166898e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
166998e386ecSGunnar Mills             {
167098e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
167198e386ecSGunnar Mills                 messages::internalError(aResp->res);
167298e386ecSGunnar Mills                 return;
167398e386ecSGunnar Mills             }
167498e386ecSGunnar Mills 
167598e386ecSGunnar Mills             const std::string& path = subtree[0].first;
167698e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
167798e386ecSGunnar Mills 
167898e386ecSGunnar Mills             if (service.empty())
167998e386ecSGunnar Mills             {
168098e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
168198e386ecSGunnar Mills                 messages::internalError(aResp->res);
168298e386ecSGunnar Mills                 return;
168398e386ecSGunnar Mills             }
168498e386ecSGunnar Mills 
168598e386ecSGunnar Mills             crow::connections::systemBus->async_method_call(
168698e386ecSGunnar Mills                 [aResp](const boost::system::error_code ec2) {
168798e386ecSGunnar Mills                     if (ec2)
168898e386ecSGunnar Mills                     {
168998e386ecSGunnar Mills                         BMCWEB_LOG_DEBUG
169098e386ecSGunnar Mills                             << "D-Bus response error on AssetTag Set " << ec2;
169198e386ecSGunnar Mills                         messages::internalError(aResp->res);
169298e386ecSGunnar Mills                         return;
169398e386ecSGunnar Mills                     }
169498e386ecSGunnar Mills                 },
169598e386ecSGunnar Mills                 service, path, "org.freedesktop.DBus.Properties", "Set",
169698e386ecSGunnar Mills                 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1697168e20c1SEd Tanous                 dbus::utility::DbusVariantType(assetTag));
169898e386ecSGunnar Mills         },
169998e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
170098e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
170198e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
170298e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
170398e386ecSGunnar Mills         std::array<const char*, 1>{
170498e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
170598e386ecSGunnar Mills }
170698e386ecSGunnar Mills 
170798e386ecSGunnar Mills /**
170869f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
170969f35306SGunnar Mills  *
171069f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
171169f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
171269f35306SGunnar Mills  *
171369f35306SGunnar Mills  * @return None.
171469f35306SGunnar Mills  */
17158d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1716f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
171769f35306SGunnar Mills {
171869f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
171969f35306SGunnar Mills 
172069f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1721543f4400SEd Tanous     bool autoRebootEnabled = false;
172269f35306SGunnar Mills 
172369f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
172469f35306SGunnar Mills     {
172569f35306SGunnar Mills         autoRebootEnabled = false;
172669f35306SGunnar Mills     }
172769f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
172869f35306SGunnar Mills     {
172969f35306SGunnar Mills         autoRebootEnabled = true;
173069f35306SGunnar Mills     }
173169f35306SGunnar Mills     else
173269f35306SGunnar Mills     {
17330fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
173469f35306SGunnar Mills                          << automaticRetryConfig;
173569f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
173669f35306SGunnar Mills                                          "AutomaticRetryConfig");
173769f35306SGunnar Mills         return;
173869f35306SGunnar Mills     }
173969f35306SGunnar Mills 
174069f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
174169f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
174269f35306SGunnar Mills             if (ec)
174369f35306SGunnar Mills             {
174469f35306SGunnar Mills                 messages::internalError(aResp->res);
174569f35306SGunnar Mills                 return;
174669f35306SGunnar Mills             }
174769f35306SGunnar Mills         },
174869f35306SGunnar Mills         "xyz.openbmc_project.Settings",
174969f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
175069f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
175169f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1752168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
175369f35306SGunnar Mills }
175469f35306SGunnar Mills 
175569f35306SGunnar Mills /**
1756c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1757c6a620f2SGeorge Liu  *
1758c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1759c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1760c6a620f2SGeorge Liu  *
1761c6a620f2SGeorge Liu  * @return None.
1762c6a620f2SGeorge Liu  */
17638d1b46d7Szhanghch05 inline void
17648d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
17654e69c904SGunnar Mills                           const std::string& policy)
1766c6a620f2SGeorge Liu {
1767c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1768c6a620f2SGeorge Liu 
1769c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
17700fda0f12SGeorge Liu         {"AlwaysOn",
17710fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
17720fda0f12SGeorge Liu         {"AlwaysOff",
17730fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
17740fda0f12SGeorge Liu         {"LastState",
17750fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1776c6a620f2SGeorge Liu 
1777c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1778c6a620f2SGeorge Liu 
17794e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1780c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1781c6a620f2SGeorge Liu     {
17824e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
17834e69c904SGunnar Mills                                          "PowerRestorePolicy");
1784c6a620f2SGeorge Liu         return;
1785c6a620f2SGeorge Liu     }
1786c6a620f2SGeorge Liu 
1787c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1788c6a620f2SGeorge Liu 
1789c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1790c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1791c6a620f2SGeorge Liu             if (ec)
1792c6a620f2SGeorge Liu             {
1793c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1794c6a620f2SGeorge Liu                 return;
1795c6a620f2SGeorge Liu             }
1796c6a620f2SGeorge Liu         },
1797c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1798c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1799c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1800c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1801168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1802c6a620f2SGeorge Liu }
1803c6a620f2SGeorge Liu 
1804a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1805a6349918SAppaRao Puli /**
1806a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1807a6349918SAppaRao Puli  *
1808a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1809a6349918SAppaRao Puli  *
1810a6349918SAppaRao Puli  * @return None.
1811a6349918SAppaRao Puli  */
18128d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1813a6349918SAppaRao Puli {
1814a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1815a6349918SAppaRao Puli     crow::connections::systemBus->async_method_call(
1816a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
1817b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1818b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1819b99fb1a9SAppaRao Puli                 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
182050626f4fSJames Feist             aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
182150626f4fSJames Feist                 "#OemComputerSystem.OpenBmc";
182250626f4fSJames Feist             oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
182350626f4fSJames Feist 
1824a6349918SAppaRao Puli             if (ec)
1825a6349918SAppaRao Puli             {
1826a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1827b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1828b99fb1a9SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1829a6349918SAppaRao Puli                 return;
1830a6349918SAppaRao Puli             }
1831a6349918SAppaRao Puli 
1832a6349918SAppaRao Puli             const bool* provState = nullptr;
1833a6349918SAppaRao Puli             const bool* lockState = nullptr;
18346e3b67ecSAppaRao Puli             for (const std::pair<std::string, dbus::utility::DbusVariantType>&
18356e3b67ecSAppaRao Puli                      property : propertiesList)
1836a6349918SAppaRao Puli             {
1837a6349918SAppaRao Puli                 if (property.first == "UfmProvisioned")
1838a6349918SAppaRao Puli                 {
1839a6349918SAppaRao Puli                     provState = std::get_if<bool>(&property.second);
1840a6349918SAppaRao Puli                 }
1841a6349918SAppaRao Puli                 else if (property.first == "UfmLocked")
1842a6349918SAppaRao Puli                 {
1843a6349918SAppaRao Puli                     lockState = std::get_if<bool>(&property.second);
1844a6349918SAppaRao Puli                 }
1845a6349918SAppaRao Puli             }
1846a6349918SAppaRao Puli 
1847a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
1848a6349918SAppaRao Puli             {
1849a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1850a6349918SAppaRao Puli                 messages::internalError(aResp->res);
1851a6349918SAppaRao Puli                 return;
1852a6349918SAppaRao Puli             }
1853a6349918SAppaRao Puli 
1854a6349918SAppaRao Puli             if (*provState == true)
1855a6349918SAppaRao Puli             {
1856a6349918SAppaRao Puli                 if (*lockState == true)
1857a6349918SAppaRao Puli                 {
1858a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1859a6349918SAppaRao Puli                 }
1860a6349918SAppaRao Puli                 else
1861a6349918SAppaRao Puli                 {
1862a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1863a6349918SAppaRao Puli                 }
1864a6349918SAppaRao Puli             }
1865a6349918SAppaRao Puli             else
1866a6349918SAppaRao Puli             {
1867a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1868a6349918SAppaRao Puli             }
1869a6349918SAppaRao Puli         },
1870a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1871a6349918SAppaRao Puli         "org.freedesktop.DBus.Properties", "GetAll",
1872a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Attributes");
1873a6349918SAppaRao Puli }
1874a6349918SAppaRao Puli #endif
1875a6349918SAppaRao Puli 
1876491d8ee7SSantosh Puranik /**
18773a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
18783a2d0424SChris Cain  *
18793a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
18803a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
18813a2d0424SChris Cain  *
18823a2d0424SChris Cain  * @return None.
18833a2d0424SChris Cain  */
18843a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18853a2d0424SChris Cain                                const std::string& modeValue)
18863a2d0424SChris Cain {
18870fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
18883a2d0424SChris Cain     {
18893a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
18903a2d0424SChris Cain     }
18910fda0f12SGeorge Liu     else if (
18920fda0f12SGeorge Liu         modeValue ==
18930fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
18943a2d0424SChris Cain     {
18953a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
18963a2d0424SChris Cain     }
18970fda0f12SGeorge Liu     else if (modeValue ==
18980fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
18993a2d0424SChris Cain     {
19003a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
19013a2d0424SChris Cain     }
19020fda0f12SGeorge Liu     else if (modeValue ==
19030fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
19043a2d0424SChris Cain     {
19053a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
19063a2d0424SChris Cain     }
19073a2d0424SChris Cain     else
19083a2d0424SChris Cain     {
19093a2d0424SChris Cain         // Any other values would be invalid
19103a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
19113a2d0424SChris Cain         messages::internalError(aResp->res);
19123a2d0424SChris Cain     }
19133a2d0424SChris Cain }
19143a2d0424SChris Cain 
19153a2d0424SChris Cain /**
19163a2d0424SChris Cain  * @brief Retrieves system power mode
19173a2d0424SChris Cain  *
19183a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19193a2d0424SChris Cain  *
19203a2d0424SChris Cain  * @return None.
19213a2d0424SChris Cain  */
19223a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
19233a2d0424SChris Cain {
19243a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
19253a2d0424SChris Cain 
19263a2d0424SChris Cain     // Get Power Mode object path:
19273a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
1928b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
1929b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
19303a2d0424SChris Cain             if (ec)
19313a2d0424SChris Cain             {
19323a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
19333a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
19343a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
19353a2d0424SChris Cain                 // error occurs
19363a2d0424SChris Cain                 return;
19373a2d0424SChris Cain             }
19383a2d0424SChris Cain             if (subtree.empty())
19393a2d0424SChris Cain             {
19403a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
19413a2d0424SChris Cain                 // if there is no instance found
19423a2d0424SChris Cain                 return;
19433a2d0424SChris Cain             }
19443a2d0424SChris Cain             if (subtree.size() > 1)
19453a2d0424SChris Cain             {
19463a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
19473a2d0424SChris Cain                 // error
19483a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
19493a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
19503a2d0424SChris Cain                     << subtree.size();
19513a2d0424SChris Cain                 messages::internalError(aResp->res);
19523a2d0424SChris Cain                 return;
19533a2d0424SChris Cain             }
19543a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
19553a2d0424SChris Cain             {
19563a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
19573a2d0424SChris Cain                 messages::internalError(aResp->res);
19583a2d0424SChris Cain                 return;
19593a2d0424SChris Cain             }
19603a2d0424SChris Cain             const std::string& path = subtree[0].first;
19613a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
19623a2d0424SChris Cain             if (service.empty())
19633a2d0424SChris Cain             {
19643a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
19653a2d0424SChris Cain                 messages::internalError(aResp->res);
19663a2d0424SChris Cain                 return;
19673a2d0424SChris Cain             }
19683a2d0424SChris Cain             // Valid Power Mode object found, now read the current value
19691e1e598dSJonathan Doman             sdbusplus::asio::getProperty<std::string>(
19701e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
19711e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
19723a2d0424SChris Cain                 [aResp](const boost::system::error_code ec,
19731e1e598dSJonathan Doman                         const std::string& pmode) {
19743a2d0424SChris Cain                     if (ec)
19753a2d0424SChris Cain                     {
19763a2d0424SChris Cain                         BMCWEB_LOG_DEBUG
19773a2d0424SChris Cain                             << "DBUS response error on PowerMode Get: " << ec;
19783a2d0424SChris Cain                         messages::internalError(aResp->res);
19793a2d0424SChris Cain                         return;
19803a2d0424SChris Cain                     }
19813a2d0424SChris Cain 
19823a2d0424SChris Cain                     aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] =
19833a2d0424SChris Cain                         {"Static", "MaximumPerformance", "PowerSaving"};
19843a2d0424SChris Cain 
19851e1e598dSJonathan Doman                     BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
19861e1e598dSJonathan Doman                     translatePowerMode(aResp, pmode);
19871e1e598dSJonathan Doman                 });
19883a2d0424SChris Cain         },
19893a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
19903a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
19913a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
19923a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
19933a2d0424SChris Cain }
19943a2d0424SChris Cain 
19953a2d0424SChris Cain /**
19963a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
19973a2d0424SChris Cain  * name associated with that string
19983a2d0424SChris Cain  *
19993a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20003a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
20013a2d0424SChris Cain  *
20023a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
20033a2d0424SChris Cain  */
20043a2d0424SChris Cain inline std::string
20053a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20063a2d0424SChris Cain                       const std::string& modeString)
20073a2d0424SChris Cain {
20083a2d0424SChris Cain     std::string mode;
20093a2d0424SChris Cain 
20103a2d0424SChris Cain     if (modeString == "Static")
20113a2d0424SChris Cain     {
20123a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
20133a2d0424SChris Cain     }
20143a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
20153a2d0424SChris Cain     {
20160fda0f12SGeorge Liu         mode =
20170fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
20183a2d0424SChris Cain     }
20193a2d0424SChris Cain     else if (modeString == "PowerSaving")
20203a2d0424SChris Cain     {
20213a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
20223a2d0424SChris Cain     }
20233a2d0424SChris Cain     else
20243a2d0424SChris Cain     {
20253a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
20263a2d0424SChris Cain     }
20273a2d0424SChris Cain     return mode;
20283a2d0424SChris Cain }
20293a2d0424SChris Cain 
20303a2d0424SChris Cain /**
20313a2d0424SChris Cain  * @brief Sets system power mode.
20323a2d0424SChris Cain  *
20333a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20343a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
20353a2d0424SChris Cain  *
20363a2d0424SChris Cain  * @return None.
20373a2d0424SChris Cain  */
20383a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20393a2d0424SChris Cain                          const std::string& pmode)
20403a2d0424SChris Cain {
20413a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
20423a2d0424SChris Cain 
20433a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
20443a2d0424SChris Cain     if (powerMode.empty())
20453a2d0424SChris Cain     {
20463a2d0424SChris Cain         return;
20473a2d0424SChris Cain     }
20483a2d0424SChris Cain 
20493a2d0424SChris Cain     // Get Power Mode object path:
20503a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
2051b9d36b47SEd Tanous         [aResp,
2052b9d36b47SEd Tanous          powerMode](const boost::system::error_code ec,
2053b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
20543a2d0424SChris Cain             if (ec)
20553a2d0424SChris Cain             {
20563a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20573a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
20583a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
20593a2d0424SChris Cain                 messages::internalError(aResp->res);
20603a2d0424SChris Cain                 return;
20613a2d0424SChris Cain             }
20623a2d0424SChris Cain             if (subtree.empty())
20633a2d0424SChris Cain             {
20643a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
20653a2d0424SChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
20663a2d0424SChris Cain                                            "PowerMode");
20673a2d0424SChris Cain                 return;
20683a2d0424SChris Cain             }
20693a2d0424SChris Cain             if (subtree.size() > 1)
20703a2d0424SChris Cain             {
20713a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
20723a2d0424SChris Cain                 // error
20733a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20743a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
20753a2d0424SChris Cain                     << subtree.size();
20763a2d0424SChris Cain                 messages::internalError(aResp->res);
20773a2d0424SChris Cain                 return;
20783a2d0424SChris Cain             }
20793a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
20803a2d0424SChris Cain             {
20813a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
20823a2d0424SChris Cain                 messages::internalError(aResp->res);
20833a2d0424SChris Cain                 return;
20843a2d0424SChris Cain             }
20853a2d0424SChris Cain             const std::string& path = subtree[0].first;
20863a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
20873a2d0424SChris Cain             if (service.empty())
20883a2d0424SChris Cain             {
20893a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20903a2d0424SChris Cain                 messages::internalError(aResp->res);
20913a2d0424SChris Cain                 return;
20923a2d0424SChris Cain             }
20933a2d0424SChris Cain 
20943a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
20953a2d0424SChris Cain                              << path;
20963a2d0424SChris Cain 
20973a2d0424SChris Cain             // Set the Power Mode property
20983a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
20993a2d0424SChris Cain                 [aResp](const boost::system::error_code ec) {
21003a2d0424SChris Cain                     if (ec)
21013a2d0424SChris Cain                     {
21023a2d0424SChris Cain                         messages::internalError(aResp->res);
21033a2d0424SChris Cain                         return;
21043a2d0424SChris Cain                     }
21053a2d0424SChris Cain                 },
21063a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
21073a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2108168e20c1SEd Tanous                 dbus::utility::DbusVariantType(powerMode));
21093a2d0424SChris Cain         },
21103a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
21113a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
21123a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
21133a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
21143a2d0424SChris Cain }
21153a2d0424SChris Cain 
21163a2d0424SChris Cain /**
211751709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
211851709ffdSYong Li  *
211951709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
212051709ffdSYong Li  *
212151709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
212251709ffdSYong Li  * translation cannot be done, returns an empty string.
212351709ffdSYong Li  */
212423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
212551709ffdSYong Li {
212651709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
212751709ffdSYong Li     {
212851709ffdSYong Li         return "None";
212951709ffdSYong Li     }
21303174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
213151709ffdSYong Li     {
213251709ffdSYong Li         return "ResetSystem";
213351709ffdSYong Li     }
21343174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
213551709ffdSYong Li     {
213651709ffdSYong Li         return "PowerDown";
213751709ffdSYong Li     }
21383174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
213951709ffdSYong Li     {
214051709ffdSYong Li         return "PowerCycle";
214151709ffdSYong Li     }
214251709ffdSYong Li 
214351709ffdSYong Li     return "";
214451709ffdSYong Li }
214551709ffdSYong Li 
214651709ffdSYong Li /**
2147c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2148c45f0082SYong Li  *
2149c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2150c45f0082SYong Li  *
2151c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2152c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2153c45f0082SYong Li  */
2154c45f0082SYong Li 
215523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2156c45f0082SYong Li {
2157c45f0082SYong Li     if (rfAction == "None")
2158c45f0082SYong Li     {
2159c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2160c45f0082SYong Li     }
21613174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2162c45f0082SYong Li     {
2163c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2164c45f0082SYong Li     }
21653174e4dfSEd Tanous     if (rfAction == "PowerDown")
2166c45f0082SYong Li     {
2167c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2168c45f0082SYong Li     }
21693174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2170c45f0082SYong Li     {
2171c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2172c45f0082SYong Li     }
2173c45f0082SYong Li 
2174c45f0082SYong Li     return "";
2175c45f0082SYong Li }
2176c45f0082SYong Li 
2177c45f0082SYong Li /**
217851709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
217951709ffdSYong Li  *
218051709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
218151709ffdSYong Li  *
218251709ffdSYong Li  * @return None.
218351709ffdSYong Li  */
21848d1b46d7Szhanghch05 inline void
21858d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
218651709ffdSYong Li {
218751709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
218851709ffdSYong Li     crow::connections::systemBus->async_method_call(
218951709ffdSYong Li         [aResp](const boost::system::error_code ec,
2190b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
219151709ffdSYong Li             if (ec)
219251709ffdSYong Li             {
219351709ffdSYong Li                 // watchdog service is stopped
219451709ffdSYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
219551709ffdSYong Li                 return;
219651709ffdSYong Li             }
219751709ffdSYong Li 
219851709ffdSYong Li             BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
219951709ffdSYong Li 
220051709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
220151709ffdSYong Li                 aResp->res.jsonValue["HostWatchdogTimer"];
220251709ffdSYong Li 
220351709ffdSYong Li             // watchdog service is running/enabled
220451709ffdSYong Li             hostWatchdogTimer["Status"]["State"] = "Enabled";
220551709ffdSYong Li 
220651709ffdSYong Li             for (const auto& property : properties)
220751709ffdSYong Li             {
220851709ffdSYong Li                 BMCWEB_LOG_DEBUG << "prop=" << property.first;
220951709ffdSYong Li                 if (property.first == "Enabled")
221051709ffdSYong Li                 {
221151709ffdSYong Li                     const bool* state = std::get_if<bool>(&property.second);
221251709ffdSYong Li 
2213e662eae8SEd Tanous                     if (state == nullptr)
221451709ffdSYong Li                     {
221551709ffdSYong Li                         messages::internalError(aResp->res);
2216601af5edSChicago Duan                         return;
221751709ffdSYong Li                     }
221851709ffdSYong Li 
221951709ffdSYong Li                     hostWatchdogTimer["FunctionEnabled"] = *state;
222051709ffdSYong Li                 }
222151709ffdSYong Li                 else if (property.first == "ExpireAction")
222251709ffdSYong Li                 {
222351709ffdSYong Li                     const std::string* s =
222451709ffdSYong Li                         std::get_if<std::string>(&property.second);
2225e662eae8SEd Tanous                     if (s == nullptr)
222651709ffdSYong Li                     {
222751709ffdSYong Li                         messages::internalError(aResp->res);
2228601af5edSChicago Duan                         return;
222951709ffdSYong Li                     }
223051709ffdSYong Li 
223151709ffdSYong Li                     std::string action = dbusToRfWatchdogAction(*s);
223251709ffdSYong Li                     if (action.empty())
223351709ffdSYong Li                     {
223451709ffdSYong Li                         messages::internalError(aResp->res);
2235601af5edSChicago Duan                         return;
223651709ffdSYong Li                     }
223751709ffdSYong Li                     hostWatchdogTimer["TimeoutAction"] = action;
223851709ffdSYong Li                 }
223951709ffdSYong Li             }
224051709ffdSYong Li         },
224151709ffdSYong Li         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
224251709ffdSYong Li         "org.freedesktop.DBus.Properties", "GetAll",
224351709ffdSYong Li         "xyz.openbmc_project.State.Watchdog");
224451709ffdSYong Li }
224551709ffdSYong Li 
224651709ffdSYong Li /**
2247c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2248c45f0082SYong Li  *
2249c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2250c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2251c45f0082SYong Li  *                       RF request.
2252c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2253c45f0082SYong Li  *
2254c45f0082SYong Li  * @return None.
2255c45f0082SYong Li  */
22568d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2257c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2258c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2259c45f0082SYong Li {
2260c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2261c45f0082SYong Li 
2262c45f0082SYong Li     if (wdtTimeOutAction)
2263c45f0082SYong Li     {
2264c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2265c45f0082SYong Li         // check if TimeOut Action is Valid
2266c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2267c45f0082SYong Li         {
2268c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2269c45f0082SYong Li                              << *wdtTimeOutAction;
2270c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2271c45f0082SYong Li                                              "TimeoutAction");
2272c45f0082SYong Li             return;
2273c45f0082SYong Li         }
2274c45f0082SYong Li 
2275c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2276c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2277c45f0082SYong Li                 if (ec)
2278c45f0082SYong Li                 {
2279c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2280c45f0082SYong Li                     messages::internalError(aResp->res);
2281c45f0082SYong Li                     return;
2282c45f0082SYong Li                 }
2283c45f0082SYong Li             },
2284c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2285c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2286c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2287c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2288168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2289c45f0082SYong Li     }
2290c45f0082SYong Li 
2291c45f0082SYong Li     if (wdtEnable)
2292c45f0082SYong Li     {
2293c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2294c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2295c45f0082SYong Li                 if (ec)
2296c45f0082SYong Li                 {
2297c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2298c45f0082SYong Li                     messages::internalError(aResp->res);
2299c45f0082SYong Li                     return;
2300c45f0082SYong Li                 }
2301c45f0082SYong Li             },
2302c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2303c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2304c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2305c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2306168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2307c45f0082SYong Li     }
2308c45f0082SYong Li }
2309c45f0082SYong Li 
231037bbf98cSChris Cain using ipsPropertiesType =
231137bbf98cSChris Cain     std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>;
231237bbf98cSChris Cain /**
231337bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
231437bbf98cSChris Cain  *
231537bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
231637bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
231737bbf98cSChris Cain  *
231837bbf98cSChris Cain  * @return true if successful
231937bbf98cSChris Cain  */
2320f6674220SEd Tanous inline bool parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
232137bbf98cSChris Cain                                ipsPropertiesType& properties)
232237bbf98cSChris Cain {
232337bbf98cSChris Cain     for (const auto& property : properties)
232437bbf98cSChris Cain     {
232537bbf98cSChris Cain         if (property.first == "Enabled")
232637bbf98cSChris Cain         {
232737bbf98cSChris Cain             const bool* state = std::get_if<bool>(&property.second);
2328e662eae8SEd Tanous             if (state == nullptr)
232937bbf98cSChris Cain             {
233037bbf98cSChris Cain                 return false;
233137bbf98cSChris Cain             }
233237bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *state;
233337bbf98cSChris Cain         }
233437bbf98cSChris Cain         else if (property.first == "EnterUtilizationPercent")
233537bbf98cSChris Cain         {
233637bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
2337e662eae8SEd Tanous             if (util == nullptr)
233837bbf98cSChris Cain             {
233937bbf98cSChris Cain                 return false;
234037bbf98cSChris Cain             }
234137bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
234237bbf98cSChris Cain         }
234337bbf98cSChris Cain         else if (property.first == "EnterDwellTime")
234437bbf98cSChris Cain         {
234537bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
234637bbf98cSChris Cain             const uint64_t* timeMilliseconds =
234737bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
2348e662eae8SEd Tanous             if (timeMilliseconds == nullptr)
234937bbf98cSChris Cain             {
235037bbf98cSChris Cain                 return false;
235137bbf98cSChris Cain             }
235237bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
235337bbf98cSChris Cain                 *timeMilliseconds);
235437bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
235537bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
235637bbf98cSChris Cain                     .count();
235737bbf98cSChris Cain         }
235837bbf98cSChris Cain         else if (property.first == "ExitUtilizationPercent")
235937bbf98cSChris Cain         {
236037bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
2361e662eae8SEd Tanous             if (util == nullptr)
236237bbf98cSChris Cain             {
236337bbf98cSChris Cain                 return false;
236437bbf98cSChris Cain             }
236537bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
236637bbf98cSChris Cain         }
236737bbf98cSChris Cain         else if (property.first == "ExitDwellTime")
236837bbf98cSChris Cain         {
236937bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
237037bbf98cSChris Cain             const uint64_t* timeMilliseconds =
237137bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
2372e662eae8SEd Tanous             if (timeMilliseconds == nullptr)
237337bbf98cSChris Cain             {
237437bbf98cSChris Cain                 return false;
237537bbf98cSChris Cain             }
237637bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
237737bbf98cSChris Cain                 *timeMilliseconds);
237837bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
237937bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
238037bbf98cSChris Cain                     .count();
238137bbf98cSChris Cain         }
238237bbf98cSChris Cain         else
238337bbf98cSChris Cain         {
238437bbf98cSChris Cain             BMCWEB_LOG_WARNING << "Unexpected IdlePowerSaver property: "
238537bbf98cSChris Cain                                << property.first;
238637bbf98cSChris Cain         }
238737bbf98cSChris Cain     }
238837bbf98cSChris Cain 
238937bbf98cSChris Cain     return true;
239037bbf98cSChris Cain }
239137bbf98cSChris Cain 
239237bbf98cSChris Cain /**
239337bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
239437bbf98cSChris Cain  *
239537bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
239637bbf98cSChris Cain  *
239737bbf98cSChris Cain  * @return None.
239837bbf98cSChris Cain  */
239937bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
240037bbf98cSChris Cain {
240137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
240237bbf98cSChris Cain 
240337bbf98cSChris Cain     // Get IdlePowerSaver object path:
240437bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
2405b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
2406b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
240737bbf98cSChris Cain             if (ec)
240837bbf98cSChris Cain             {
240937bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
241037bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
241137bbf98cSChris Cain                     << ec;
241237bbf98cSChris Cain                 messages::internalError(aResp->res);
241337bbf98cSChris Cain                 return;
241437bbf98cSChris Cain             }
241537bbf98cSChris Cain             if (subtree.empty())
241637bbf98cSChris Cain             {
241737bbf98cSChris Cain                 // This is an optional interface so just return
241837bbf98cSChris Cain                 // if there is no instance found
241937bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "No instances found";
242037bbf98cSChris Cain                 return;
242137bbf98cSChris Cain             }
242237bbf98cSChris Cain             if (subtree.size() > 1)
242337bbf98cSChris Cain             {
242437bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
242537bbf98cSChris Cain                 // is an error
242637bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
242737bbf98cSChris Cain                                     "Power.IdlePowerSaver objects: "
242837bbf98cSChris Cain                                  << subtree.size();
242937bbf98cSChris Cain                 messages::internalError(aResp->res);
243037bbf98cSChris Cain                 return;
243137bbf98cSChris Cain             }
243237bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
243337bbf98cSChris Cain             {
243437bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
243537bbf98cSChris Cain                 messages::internalError(aResp->res);
243637bbf98cSChris Cain                 return;
243737bbf98cSChris Cain             }
243837bbf98cSChris Cain             const std::string& path = subtree[0].first;
243937bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
244037bbf98cSChris Cain             if (service.empty())
244137bbf98cSChris Cain             {
244237bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
244337bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
244437bbf98cSChris Cain                 messages::internalError(aResp->res);
244537bbf98cSChris Cain                 return;
244637bbf98cSChris Cain             }
244737bbf98cSChris Cain 
244837bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
244937bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
245037bbf98cSChris Cain                 [aResp](const boost::system::error_code ec,
245137bbf98cSChris Cain                         ipsPropertiesType& properties) {
245237bbf98cSChris Cain                     if (ec)
245337bbf98cSChris Cain                     {
245437bbf98cSChris Cain                         BMCWEB_LOG_ERROR
245537bbf98cSChris Cain                             << "DBUS response error on IdlePowerSaver GetAll: "
245637bbf98cSChris Cain                             << ec;
245737bbf98cSChris Cain                         messages::internalError(aResp->res);
245837bbf98cSChris Cain                         return;
245937bbf98cSChris Cain                     }
246037bbf98cSChris Cain 
2461e05aec50SEd Tanous                     if (!parseIpsProperties(aResp, properties))
246237bbf98cSChris Cain                     {
246337bbf98cSChris Cain                         messages::internalError(aResp->res);
246437bbf98cSChris Cain                         return;
246537bbf98cSChris Cain                     }
246637bbf98cSChris Cain                 },
246737bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "GetAll",
246837bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver");
246937bbf98cSChris Cain         },
247037bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
247137bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
247237bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
247337bbf98cSChris Cain         std::array<const char*, 1>{
247437bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
247537bbf98cSChris Cain 
247637bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
247737bbf98cSChris Cain }
247837bbf98cSChris Cain 
247937bbf98cSChris Cain /**
248037bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
248137bbf98cSChris Cain  *
248237bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
248337bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
248437bbf98cSChris Cain  *                       RF request.
248537bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
248637bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
248737bbf98cSChris Cain  * before entering idle state.
248837bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
248937bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
249037bbf98cSChris Cain  * before exiting idle state
249137bbf98cSChris Cain  *
249237bbf98cSChris Cain  * @return None.
249337bbf98cSChris Cain  */
249437bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
249537bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
249637bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
249737bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
249837bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
249937bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
250037bbf98cSChris Cain {
250137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
250237bbf98cSChris Cain 
250337bbf98cSChris Cain     // Get IdlePowerSaver object path:
250437bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
250537bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2506b9d36b47SEd Tanous          ipsExitTime](const boost::system::error_code ec,
2507b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
250837bbf98cSChris Cain             if (ec)
250937bbf98cSChris Cain             {
251037bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
251137bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
251237bbf98cSChris Cain                     << ec;
251337bbf98cSChris Cain                 messages::internalError(aResp->res);
251437bbf98cSChris Cain                 return;
251537bbf98cSChris Cain             }
251637bbf98cSChris Cain             if (subtree.empty())
251737bbf98cSChris Cain             {
251837bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
251937bbf98cSChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
252037bbf98cSChris Cain                                            "IdlePowerSaver");
252137bbf98cSChris Cain                 return;
252237bbf98cSChris Cain             }
252337bbf98cSChris Cain             if (subtree.size() > 1)
252437bbf98cSChris Cain             {
252537bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
252637bbf98cSChris Cain                 // is an error
25270fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
25280fda0f12SGeorge Liu                     << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
252937bbf98cSChris Cain                     << subtree.size();
253037bbf98cSChris Cain                 messages::internalError(aResp->res);
253137bbf98cSChris Cain                 return;
253237bbf98cSChris Cain             }
253337bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
253437bbf98cSChris Cain             {
253537bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
253637bbf98cSChris Cain                 messages::internalError(aResp->res);
253737bbf98cSChris Cain                 return;
253837bbf98cSChris Cain             }
253937bbf98cSChris Cain             const std::string& path = subtree[0].first;
254037bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
254137bbf98cSChris Cain             if (service.empty())
254237bbf98cSChris Cain             {
254337bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
254437bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
254537bbf98cSChris Cain                 messages::internalError(aResp->res);
254637bbf98cSChris Cain                 return;
254737bbf98cSChris Cain             }
254837bbf98cSChris Cain 
254937bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
255037bbf98cSChris Cain             // need to be updated
255137bbf98cSChris Cain 
255237bbf98cSChris Cain             if (ipsEnable)
255337bbf98cSChris Cain             {
255437bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
255537bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
255637bbf98cSChris Cain                         if (ec)
255737bbf98cSChris Cain                         {
255837bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
255937bbf98cSChris Cain                             messages::internalError(aResp->res);
256037bbf98cSChris Cain                             return;
256137bbf98cSChris Cain                         }
256237bbf98cSChris Cain                     },
256337bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
256437bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2565168e20c1SEd Tanous                     "Enabled", dbus::utility::DbusVariantType(*ipsEnable));
256637bbf98cSChris Cain             }
256737bbf98cSChris Cain             if (ipsEnterUtil)
256837bbf98cSChris Cain             {
256937bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
257037bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
257137bbf98cSChris Cain                         if (ec)
257237bbf98cSChris Cain                         {
257337bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
257437bbf98cSChris Cain                             messages::internalError(aResp->res);
257537bbf98cSChris Cain                             return;
257637bbf98cSChris Cain                         }
257737bbf98cSChris Cain                     },
257837bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
257937bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
258037bbf98cSChris Cain                     "EnterUtilizationPercent",
2581168e20c1SEd Tanous                     dbus::utility::DbusVariantType(*ipsEnterUtil));
258237bbf98cSChris Cain             }
258337bbf98cSChris Cain             if (ipsEnterTime)
258437bbf98cSChris Cain             {
258537bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
258637bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
258737bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
258837bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
258937bbf98cSChris Cain                         if (ec)
259037bbf98cSChris Cain                         {
259137bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
259237bbf98cSChris Cain                             messages::internalError(aResp->res);
259337bbf98cSChris Cain                             return;
259437bbf98cSChris Cain                         }
259537bbf98cSChris Cain                     },
259637bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
259737bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2598168e20c1SEd Tanous                     "EnterDwellTime",
2599168e20c1SEd Tanous                     dbus::utility::DbusVariantType(timeMilliseconds));
260037bbf98cSChris Cain             }
260137bbf98cSChris Cain             if (ipsExitUtil)
260237bbf98cSChris Cain             {
260337bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
260437bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
260537bbf98cSChris Cain                         if (ec)
260637bbf98cSChris Cain                         {
260737bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
260837bbf98cSChris Cain                             messages::internalError(aResp->res);
260937bbf98cSChris Cain                             return;
261037bbf98cSChris Cain                         }
261137bbf98cSChris Cain                     },
261237bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
261337bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
261437bbf98cSChris Cain                     "ExitUtilizationPercent",
2615168e20c1SEd Tanous                     dbus::utility::DbusVariantType(*ipsExitUtil));
261637bbf98cSChris Cain             }
261737bbf98cSChris Cain             if (ipsExitTime)
261837bbf98cSChris Cain             {
261937bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
262037bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
262137bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
262237bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
262337bbf98cSChris Cain                         if (ec)
262437bbf98cSChris Cain                         {
262537bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
262637bbf98cSChris Cain                             messages::internalError(aResp->res);
262737bbf98cSChris Cain                             return;
262837bbf98cSChris Cain                         }
262937bbf98cSChris Cain                     },
263037bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
263137bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2632168e20c1SEd Tanous                     "ExitDwellTime",
2633168e20c1SEd Tanous                     dbus::utility::DbusVariantType(timeMilliseconds));
263437bbf98cSChris Cain             }
263537bbf98cSChris Cain         },
263637bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
263737bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
263837bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
263937bbf98cSChris Cain         std::array<const char*, 1>{
264037bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
264137bbf98cSChris Cain 
264237bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
264337bbf98cSChris Cain }
264437bbf98cSChris Cain 
2645c45f0082SYong Li /**
2646c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2647c5b2abe0SLewanczyk, Dawid  * Schema
2648c5b2abe0SLewanczyk, Dawid  */
26497e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
26501abe55efSEd Tanous {
26517e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2652ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
26537e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2654f4c99e70SEd Tanous             [&app](const crow::Request& req,
26557e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2656f4c99e70SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
2657f4c99e70SEd Tanous                 {
2658f4c99e70SEd Tanous                     return;
2659f4c99e70SEd Tanous                 }
26608d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
26610f74e643SEd Tanous                     "#ComputerSystemCollection.ComputerSystemCollection";
26628d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
26638d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2664462023adSSunitha Harish 
26651e1e598dSJonathan Doman                 sdbusplus::asio::getProperty<std::string>(
26661e1e598dSJonathan Doman                     *crow::connections::systemBus,
26671e1e598dSJonathan Doman                     "xyz.openbmc_project.Settings",
26681e1e598dSJonathan Doman                     "/xyz/openbmc_project/network/hypervisor",
26691e1e598dSJonathan Doman                     "xyz.openbmc_project.Network.SystemConfiguration",
26701e1e598dSJonathan Doman                     "HostName",
26711e1e598dSJonathan Doman                     [asyncResp](const boost::system::error_code ec,
26721e1e598dSJonathan Doman                                 const std::string& /*hostName*/) {
26732c70f800SEd Tanous                         nlohmann::json& ifaceArray =
2674462023adSSunitha Harish                             asyncResp->res.jsonValue["Members"];
26752c70f800SEd Tanous                         ifaceArray = nlohmann::json::array();
26767e860f15SJohn Edward Broadbent                         auto& count =
26777e860f15SJohn Edward Broadbent                             asyncResp->res.jsonValue["Members@odata.count"];
26781476687dSEd Tanous 
26791476687dSEd Tanous                         nlohmann::json::object_t system;
26801476687dSEd Tanous                         system["@odata.id"] = "/redfish/v1/Systems/system";
26811476687dSEd Tanous                         ifaceArray.push_back(std::move(system));
268294bda602STim Lee                         count = ifaceArray.size();
2683cb13a392SEd Tanous                         if (!ec)
2684462023adSSunitha Harish                         {
2685462023adSSunitha Harish                             BMCWEB_LOG_DEBUG << "Hypervisor is available";
26861476687dSEd Tanous                             nlohmann::json::object_t hypervisor;
26871476687dSEd Tanous                             hypervisor["@odata.id"] =
26881476687dSEd Tanous                                 "/redfish/v1/Systems/hypervisor";
26891476687dSEd Tanous                             ifaceArray.push_back(std::move(hypervisor));
26902c70f800SEd Tanous                             count = ifaceArray.size();
2691cb13a392SEd Tanous                         }
26921e1e598dSJonathan Doman                     });
26937e860f15SJohn Edward Broadbent             });
2694c5b2abe0SLewanczyk, Dawid }
26957e860f15SJohn Edward Broadbent 
26967e860f15SJohn Edward Broadbent /**
26977e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
26987e860f15SJohn Edward Broadbent  */
26994f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27007e860f15SJohn Edward Broadbent {
27017e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
27027e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
27037e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
27047e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
27057e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
27067e860f15SJohn Edward Broadbent 
27077e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
27087e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
27097e860f15SJohn Edward Broadbent             if (ec)
27107e860f15SJohn Edward Broadbent             {
27117e860f15SJohn Edward Broadbent                 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
27127e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
27137e860f15SJohn Edward Broadbent                 return;
27147e860f15SJohn Edward Broadbent             }
27157e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
27167e860f15SJohn Edward Broadbent         },
27177e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
27187e860f15SJohn Edward Broadbent }
2719c5b2abe0SLewanczyk, Dawid 
2720c5b2abe0SLewanczyk, Dawid /**
2721cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2722cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2723cc340dd9SEd Tanous  */
27247e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2725cc340dd9SEd Tanous {
2726cc340dd9SEd Tanous     /**
2727cc340dd9SEd Tanous      * Function handles POST method request.
2728cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2729cc340dd9SEd Tanous      */
27307e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
27317e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2732ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
27337e860f15SJohn Edward Broadbent         .methods(
27347e860f15SJohn Edward Broadbent             boost::beast::http::verb::
273545ca1b86SEd Tanous                 post)([&app](
273645ca1b86SEd Tanous                           const crow::Request& req,
27377e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
273845ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
273945ca1b86SEd Tanous             {
274045ca1b86SEd Tanous                 return;
274145ca1b86SEd Tanous             }
27429712f8acSEd Tanous             std::string resetType;
274315ed6780SWilly Tu             if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
27447e860f15SJohn Edward Broadbent                                            resetType))
2745cc340dd9SEd Tanous             {
2746cc340dd9SEd Tanous                 return;
2747cc340dd9SEd Tanous             }
2748cc340dd9SEd Tanous 
2749d22c8396SJason M. Bills             // Get the command and host vs. chassis
2750cc340dd9SEd Tanous             std::string command;
2751543f4400SEd Tanous             bool hostCommand = true;
2752d4d25793SEd Tanous             if ((resetType == "On") || (resetType == "ForceOn"))
2753cc340dd9SEd Tanous             {
2754cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.On";
2755d22c8396SJason M. Bills                 hostCommand = true;
2756d22c8396SJason M. Bills             }
2757d22c8396SJason M. Bills             else if (resetType == "ForceOff")
2758d22c8396SJason M. Bills             {
2759d22c8396SJason M. Bills                 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2760d22c8396SJason M. Bills                 hostCommand = false;
2761d22c8396SJason M. Bills             }
2762d22c8396SJason M. Bills             else if (resetType == "ForceRestart")
2763d22c8396SJason M. Bills             {
276486a0851aSJason M. Bills                 command =
276586a0851aSJason M. Bills                     "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
276686a0851aSJason M. Bills                 hostCommand = true;
2767cc340dd9SEd Tanous             }
27689712f8acSEd Tanous             else if (resetType == "GracefulShutdown")
2769cc340dd9SEd Tanous             {
2770cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.Off";
2771d22c8396SJason M. Bills                 hostCommand = true;
2772cc340dd9SEd Tanous             }
27739712f8acSEd Tanous             else if (resetType == "GracefulRestart")
2774cc340dd9SEd Tanous             {
27750fda0f12SGeorge Liu                 command =
27760fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2777d22c8396SJason M. Bills                 hostCommand = true;
2778d22c8396SJason M. Bills             }
2779d22c8396SJason M. Bills             else if (resetType == "PowerCycle")
2780d22c8396SJason M. Bills             {
278186a0851aSJason M. Bills                 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
278286a0851aSJason M. Bills                 hostCommand = true;
2783cc340dd9SEd Tanous             }
2784bfd5b826SLakshminarayana R. Kammath             else if (resetType == "Nmi")
2785bfd5b826SLakshminarayana R. Kammath             {
2786bfd5b826SLakshminarayana R. Kammath                 doNMI(asyncResp);
2787bfd5b826SLakshminarayana R. Kammath                 return;
2788bfd5b826SLakshminarayana R. Kammath             }
2789cc340dd9SEd Tanous             else
2790cc340dd9SEd Tanous             {
27918d1b46d7Szhanghch05                 messages::actionParameterUnknown(asyncResp->res, "Reset",
27928d1b46d7Szhanghch05                                                  resetType);
2793cc340dd9SEd Tanous                 return;
2794cc340dd9SEd Tanous             }
2795cc340dd9SEd Tanous 
2796d22c8396SJason M. Bills             if (hostCommand)
2797d22c8396SJason M. Bills             {
2798cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
2799d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2800cc340dd9SEd Tanous                         if (ec)
2801cc340dd9SEd Tanous                         {
2802cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
28037e860f15SJohn Edward Broadbent                             if (ec.value() ==
28047e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2805d22c8396SJason M. Bills                             {
2806d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2807d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2808d22c8396SJason M. Bills                             }
2809d22c8396SJason M. Bills                             else
2810d22c8396SJason M. Bills                             {
2811f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
2812d22c8396SJason M. Bills                             }
2813cc340dd9SEd Tanous                             return;
2814cc340dd9SEd Tanous                         }
2815f12894f8SJason M. Bills                         messages::success(asyncResp->res);
2816cc340dd9SEd Tanous                     },
2817cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
2818cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
2819cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
28209712f8acSEd Tanous                     "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2821168e20c1SEd Tanous                     dbus::utility::DbusVariantType{command});
2822cc340dd9SEd Tanous             }
2823d22c8396SJason M. Bills             else
2824d22c8396SJason M. Bills             {
2825d22c8396SJason M. Bills                 crow::connections::systemBus->async_method_call(
2826d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2827d22c8396SJason M. Bills                         if (ec)
2828d22c8396SJason M. Bills                         {
2829d22c8396SJason M. Bills                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
28307e860f15SJohn Edward Broadbent                             if (ec.value() ==
28317e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2832d22c8396SJason M. Bills                             {
2833d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2834d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2835d22c8396SJason M. Bills                             }
2836d22c8396SJason M. Bills                             else
2837d22c8396SJason M. Bills                             {
2838d22c8396SJason M. Bills                                 messages::internalError(asyncResp->res);
2839d22c8396SJason M. Bills                             }
2840d22c8396SJason M. Bills                             return;
2841d22c8396SJason M. Bills                         }
2842d22c8396SJason M. Bills                         messages::success(asyncResp->res);
2843d22c8396SJason M. Bills                     },
2844d22c8396SJason M. Bills                     "xyz.openbmc_project.State.Chassis",
2845d22c8396SJason M. Bills                     "/xyz/openbmc_project/state/chassis0",
2846d22c8396SJason M. Bills                     "org.freedesktop.DBus.Properties", "Set",
28477e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.State.Chassis",
28487e860f15SJohn Edward Broadbent                     "RequestedPowerTransition",
2849168e20c1SEd Tanous                     dbus::utility::DbusVariantType{command});
2850d22c8396SJason M. Bills             }
28517e860f15SJohn Edward Broadbent         });
2852d22c8396SJason M. Bills }
2853cc340dd9SEd Tanous 
2854cc340dd9SEd Tanous /**
28556617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2856c5b2abe0SLewanczyk, Dawid  */
28577e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
28581abe55efSEd Tanous {
2859c5b2abe0SLewanczyk, Dawid 
2860c5b2abe0SLewanczyk, Dawid     /**
2861c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2862c5b2abe0SLewanczyk, Dawid      */
28637e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2864ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
286545ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
286645ca1b86SEd Tanous                                                        const std::shared_ptr<
286745ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
286845ca1b86SEd Tanous                                                            asyncResp) {
286945ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
287045ca1b86SEd Tanous             {
287145ca1b86SEd Tanous                 return;
287245ca1b86SEd Tanous             }
28738d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.type"] =
287437bbf98cSChris Cain                 "#ComputerSystem.v1_16_0.ComputerSystem";
28758d1b46d7Szhanghch05             asyncResp->res.jsonValue["Name"] = "system";
28768d1b46d7Szhanghch05             asyncResp->res.jsonValue["Id"] = "system";
28778d1b46d7Szhanghch05             asyncResp->res.jsonValue["SystemType"] = "Physical";
28788d1b46d7Szhanghch05             asyncResp->res.jsonValue["Description"] = "Computer System";
28798d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
28808d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
28818d1b46d7Szhanghch05                 "Disabled";
28828d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
28838d1b46d7Szhanghch05                 uint64_t(0);
28848d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
28858d1b46d7Szhanghch05                 "Disabled";
28867e860f15SJohn Edward Broadbent             asyncResp->res.jsonValue["@odata.id"] =
28877e860f15SJohn Edward Broadbent                 "/redfish/v1/Systems/system";
288804a258f4SEd Tanous 
28891476687dSEd Tanous             asyncResp->res.jsonValue["Processors"]["@odata.id"] =
28901476687dSEd Tanous                 "/redfish/v1/Systems/system/Processors";
28911476687dSEd Tanous             asyncResp->res.jsonValue["Memory"]["@odata.id"] =
28921476687dSEd Tanous                 "/redfish/v1/Systems/system/Memory";
28931476687dSEd Tanous             asyncResp->res.jsonValue["Storage"]["@odata.id"] =
28941476687dSEd Tanous                 "/redfish/v1/Systems/system/Storage";
2895029573d4SEd Tanous 
28961476687dSEd Tanous             asyncResp->res
28971476687dSEd Tanous                 .jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
28981476687dSEd Tanous                 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
28991476687dSEd Tanous             asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
29001476687dSEd Tanous                                     ["@Redfish.ActionInfo"] =
29011476687dSEd Tanous                 "/redfish/v1/Systems/system/ResetActionInfo";
2902c5b2abe0SLewanczyk, Dawid 
29031476687dSEd Tanous             asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
29041476687dSEd Tanous                 "/redfish/v1/Systems/system/LogServices";
29051476687dSEd Tanous             asyncResp->res.jsonValue["Bios"]["@odata.id"] =
29061476687dSEd Tanous                 "/redfish/v1/Systems/system/Bios";
2907c4bf6374SJason M. Bills 
29081476687dSEd Tanous             nlohmann::json::array_t managedBy;
29091476687dSEd Tanous             nlohmann::json& manager = managedBy.emplace_back();
29101476687dSEd Tanous             manager["@odata.id"] = "/redfish/v1/Managers/bmc";
29111476687dSEd Tanous             asyncResp->res.jsonValue["Links"]["ManagedBy"] =
29121476687dSEd Tanous                 std::move(managedBy);
29131476687dSEd Tanous             asyncResp->res.jsonValue["Status"]["Health"] = "OK";
29141476687dSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
29150e8ac5e7SGunnar Mills 
29160e8ac5e7SGunnar Mills             // Fill in SerialConsole info
29170e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
29180e8ac5e7SGunnar Mills                 15;
29191476687dSEd Tanous             asyncResp->res
29201476687dSEd Tanous                 .jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
29211476687dSEd Tanous 
29220e8ac5e7SGunnar Mills             // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
29231476687dSEd Tanous             asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
29241476687dSEd Tanous                 true;
29251476687dSEd Tanous             asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
29261476687dSEd Tanous             asyncResp->res
29271476687dSEd Tanous                 .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
29281476687dSEd Tanous                 "Press ~. to exit console";
29290e8ac5e7SGunnar Mills 
29300e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
29310e8ac5e7SGunnar Mills             // Fill in GraphicalConsole info
29321476687dSEd Tanous             asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] =
29331476687dSEd Tanous                 true;
29341476687dSEd Tanous             asyncResp->res
29351476687dSEd Tanous                 .jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
29361476687dSEd Tanous             asyncResp->res.jsonValue["GraphicalConsole"]
29371476687dSEd Tanous                                     ["ConnectTypesSupported"] = {"KVMIP"};
29381476687dSEd Tanous 
29390e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
2940e284a7c1SJames Feist             constexpr const std::array<const char*, 4> inventoryForSystems = {
2941b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
29422ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
2943e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
2944e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
2945b49ac873SJames Feist 
2946b49ac873SJames Feist             auto health = std::make_shared<HealthPopulate>(asyncResp);
2947b49ac873SJames Feist             crow::connections::systemBus->async_method_call(
2948b49ac873SJames Feist                 [health](const boost::system::error_code ec,
2949914e2d5dSEd Tanous                          const std::vector<std::string>& resp) {
2950b49ac873SJames Feist                     if (ec)
2951b49ac873SJames Feist                     {
2952b49ac873SJames Feist                         // no inventory
2953b49ac873SJames Feist                         return;
2954b49ac873SJames Feist                     }
2955b49ac873SJames Feist 
2956914e2d5dSEd Tanous                     health->inventory = resp;
2957b49ac873SJames Feist                 },
2958b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper",
2959b49ac873SJames Feist                 "/xyz/openbmc_project/object_mapper",
2960b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2961b49ac873SJames Feist                 int32_t(0), inventoryForSystems);
2962b49ac873SJames Feist 
2963b49ac873SJames Feist             health->populate();
2964b49ac873SJames Feist 
29658d1b46d7Szhanghch05             getMainChassisId(
29668d1b46d7Szhanghch05                 asyncResp, [](const std::string& chassisId,
29678d1b46d7Szhanghch05                               const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2968b2c7e208SEd Tanous                     nlohmann::json::array_t chassisArray;
2969b2c7e208SEd Tanous                     nlohmann::json& chassis = chassisArray.emplace_back();
2970b2c7e208SEd Tanous                     chassis["@odata.id"] = "/redfish/v1/Chassis/" + chassisId;
2971b2c7e208SEd Tanous                     aRsp->res.jsonValue["Links"]["Chassis"] =
2972b2c7e208SEd Tanous                         std::move(chassisArray);
2973c5d03ff4SJennifer Lee                 });
2974a3002228SAppaRao Puli 
29759f8bfa7cSGunnar Mills             getLocationIndicatorActive(asyncResp);
29769f8bfa7cSGunnar Mills             // TODO (Gunnar): Remove IndicatorLED after enough time has passed
2977a3002228SAppaRao Puli             getIndicatorLedState(asyncResp);
29785bc2dc8eSJames Feist             getComputerSystem(asyncResp, health);
29796c34de48SEd Tanous             getHostState(asyncResp);
2980491d8ee7SSantosh Puranik             getBootProperties(asyncResp);
2981978b8803SAndrew Geissler             getBootProgress(asyncResp);
2982adbe192aSJason M. Bills             getPCIeDeviceList(asyncResp, "PCIeDevices");
298351709ffdSYong Li             getHostWatchdogTimer(asyncResp);
2984c6a620f2SGeorge Liu             getPowerRestorePolicy(asyncResp);
29856bd5a8d2SGunnar Mills             getAutomaticRetry(asyncResp);
2986c0557e1aSGunnar Mills             getLastResetTime(asyncResp);
2987a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2988a6349918SAppaRao Puli             getProvisioningStatus(asyncResp);
2989a6349918SAppaRao Puli #endif
29901981771bSAli Ahmed             getTrustedModuleRequiredToBoot(asyncResp);
29913a2d0424SChris Cain             getPowerMode(asyncResp);
299237bbf98cSChris Cain             getIdlePowerSaver(asyncResp);
29937e860f15SJohn Edward Broadbent         });
2994550a6bf8SJiaqing Zhao 
29957e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2996ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
29977e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
299845ca1b86SEd Tanous             [&app](const crow::Request& req,
29997e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
300045ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
300145ca1b86SEd Tanous                 {
300245ca1b86SEd Tanous                     return;
300345ca1b86SEd Tanous                 }
30049f8bfa7cSGunnar Mills                 std::optional<bool> locationIndicatorActive;
3005cde19e5fSSantosh Puranik                 std::optional<std::string> indicatorLed;
300698e386ecSGunnar Mills                 std::optional<std::string> assetTag;
3007c6a620f2SGeorge Liu                 std::optional<std::string> powerRestorePolicy;
30083a2d0424SChris Cain                 std::optional<std::string> powerMode;
3009550a6bf8SJiaqing Zhao                 std::optional<bool> wdtEnable;
3010550a6bf8SJiaqing Zhao                 std::optional<std::string> wdtTimeOutAction;
3011550a6bf8SJiaqing Zhao                 std::optional<std::string> bootSource;
3012550a6bf8SJiaqing Zhao                 std::optional<std::string> bootType;
3013550a6bf8SJiaqing Zhao                 std::optional<std::string> bootEnable;
3014550a6bf8SJiaqing Zhao                 std::optional<std::string> bootAutomaticRetry;
3015550a6bf8SJiaqing Zhao                 std::optional<bool> bootTrustedModuleRequired;
3016550a6bf8SJiaqing Zhao                 std::optional<bool> ipsEnable;
3017550a6bf8SJiaqing Zhao                 std::optional<uint8_t> ipsEnterUtil;
3018550a6bf8SJiaqing Zhao                 std::optional<uint64_t> ipsEnterTime;
3019550a6bf8SJiaqing Zhao                 std::optional<uint8_t> ipsExitUtil;
3020550a6bf8SJiaqing Zhao                 std::optional<uint64_t> ipsExitTime;
3021550a6bf8SJiaqing Zhao 
3022550a6bf8SJiaqing Zhao                 // clang-format off
302315ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3024550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3025550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
30267e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3027550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3028550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3029550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3030550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3031550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3032550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3033550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3034550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3035550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3036550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3037550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3038550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3039550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3040550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3041550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
30426617338dSEd Tanous                 {
30436617338dSEd Tanous                     return;
30446617338dSEd Tanous                 }
3045550a6bf8SJiaqing Zhao                 // clang-format on
3046491d8ee7SSantosh Puranik 
30478d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
3048c45f0082SYong Li 
304998e386ecSGunnar Mills                 if (assetTag)
305098e386ecSGunnar Mills                 {
305198e386ecSGunnar Mills                     setAssetTag(asyncResp, *assetTag);
305298e386ecSGunnar Mills                 }
305398e386ecSGunnar Mills 
3054550a6bf8SJiaqing Zhao                 if (wdtEnable || wdtTimeOutAction)
3055c45f0082SYong Li                 {
3056f23b7296SEd Tanous                     setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3057c45f0082SYong Li                 }
3058c45f0082SYong Li 
3059cd9a4666SKonstantin Aladyshev                 if (bootSource || bootType || bootEnable)
306069f35306SGunnar Mills                 {
3061c21865c4SKonstantin Aladyshev                     setBootProperties(asyncResp, bootSource, bootType,
3062c21865c4SKonstantin Aladyshev                                       bootEnable);
3063491d8ee7SSantosh Puranik                 }
3064550a6bf8SJiaqing Zhao                 if (bootAutomaticRetry)
306569f35306SGunnar Mills                 {
3066550a6bf8SJiaqing Zhao                     setAutomaticRetry(asyncResp, *bootAutomaticRetry);
306769f35306SGunnar Mills                 }
3068ac7e1e0bSAli Ahmed 
3069550a6bf8SJiaqing Zhao                 if (bootTrustedModuleRequired)
3070ac7e1e0bSAli Ahmed                 {
3071550a6bf8SJiaqing Zhao                     setTrustedModuleRequiredToBoot(asyncResp,
3072550a6bf8SJiaqing Zhao                                                    *bootTrustedModuleRequired);
307369f35306SGunnar Mills                 }
3074265c1602SJohnathan Mantey 
30759f8bfa7cSGunnar Mills                 if (locationIndicatorActive)
30769f8bfa7cSGunnar Mills                 {
30777e860f15SJohn Edward Broadbent                     setLocationIndicatorActive(asyncResp,
30787e860f15SJohn Edward Broadbent                                                *locationIndicatorActive);
30799f8bfa7cSGunnar Mills                 }
30809f8bfa7cSGunnar Mills 
30817e860f15SJohn Edward Broadbent                 // TODO (Gunnar): Remove IndicatorLED after enough time has
30827e860f15SJohn Edward Broadbent                 // passed
30839712f8acSEd Tanous                 if (indicatorLed)
30846617338dSEd Tanous                 {
3085f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
30867e860f15SJohn Edward Broadbent                     asyncResp->res.addHeader(
30877e860f15SJohn Edward Broadbent                         boost::beast::http::field::warning,
3088d6aa0093SGunnar Mills                         "299 - \"IndicatorLED is deprecated. Use "
3089d6aa0093SGunnar Mills                         "LocationIndicatorActive instead.\"");
30906617338dSEd Tanous                 }
3091c6a620f2SGeorge Liu 
3092c6a620f2SGeorge Liu                 if (powerRestorePolicy)
3093c6a620f2SGeorge Liu                 {
30944e69c904SGunnar Mills                     setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3095c6a620f2SGeorge Liu                 }
30963a2d0424SChris Cain 
30973a2d0424SChris Cain                 if (powerMode)
30983a2d0424SChris Cain                 {
30993a2d0424SChris Cain                     setPowerMode(asyncResp, *powerMode);
31003a2d0424SChris Cain                 }
310137bbf98cSChris Cain 
3102550a6bf8SJiaqing Zhao                 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3103550a6bf8SJiaqing Zhao                     ipsExitTime)
310437bbf98cSChris Cain                 {
310537bbf98cSChris Cain                     setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil,
310637bbf98cSChris Cain                                       ipsEnterTime, ipsExitUtil, ipsExitTime);
310737bbf98cSChris Cain                 }
31087e860f15SJohn Edward Broadbent             });
3109c5b2abe0SLewanczyk, Dawid }
31101cb1a9e6SAppaRao Puli 
31111cb1a9e6SAppaRao Puli /**
31121cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
31131cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
31141cb1a9e6SAppaRao Puli  */
31157e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
31161cb1a9e6SAppaRao Puli {
31171cb1a9e6SAppaRao Puli     /**
31181cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
31191cb1a9e6SAppaRao Puli      */
31207e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3121ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
31227e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
312345ca1b86SEd Tanous             [&app](const crow::Request& req,
31247e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
312545ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
312645ca1b86SEd Tanous                 {
312745ca1b86SEd Tanous                     return;
312845ca1b86SEd Tanous                 }
31291476687dSEd Tanous 
31301476687dSEd Tanous                 asyncResp->res.jsonValue["@odata.id"] =
31311476687dSEd Tanous                     "/redfish/v1/Systems/system/ResetActionInfo";
31321476687dSEd Tanous                 asyncResp->res.jsonValue["@odata.type"] =
31331476687dSEd Tanous                     "#ActionInfo.v1_1_2.ActionInfo";
31341476687dSEd Tanous                 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
31351476687dSEd Tanous                 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
31361476687dSEd Tanous                 asyncResp->res.jsonValue["Parameters"]["Name"] = "ResetType";
31371476687dSEd Tanous                 asyncResp->res.jsonValue["Parameters"]["Required"] = true;
31381476687dSEd Tanous                 asyncResp->res.jsonValue["Parameters"]["DataType"] = "String";
31391476687dSEd Tanous                 asyncResp->res.jsonValue["Parameters"]["AllowableValues"] = {
31401476687dSEd Tanous                     "On",
31411476687dSEd Tanous                     "ForceOff",
31421476687dSEd Tanous                     "ForceOn",
31431476687dSEd Tanous                     "ForceRestart",
31441476687dSEd Tanous                     "GracefulRestart",
31451476687dSEd Tanous                     "GracefulShutdown",
31461476687dSEd Tanous                     "PowerCycle",
31471476687dSEd Tanous                     "Nmi"};
31487e860f15SJohn Edward Broadbent             });
31491cb1a9e6SAppaRao Puli }
3150c5b2abe0SLewanczyk, Dawid } // namespace redfish
3151