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