xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 0fda0f12bb9ae0604a083dfae419be38a1418913)
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
351*0fda0f12SGeorge Liu                                                     << "Find incorrect type of MemorySize";
3525fd7ba65SCheng C Yang                                                 continue;
3535fd7ba65SCheng C Yang                                             }
3545fd7ba65SCheng C Yang                                             nlohmann::json& totalMemory =
355*0fda0f12SGeorge Liu                                                 aResp->res.jsonValue
356*0fda0f12SGeorge Liu                                                     ["MemorySummary"]
357*0fda0f12SGeorge Liu                                                     ["TotalSystemMemoryGiB"];
3585fd7ba65SCheng C Yang                                             uint64_t* preValue =
3595fd7ba65SCheng C Yang                                                 totalMemory
3605fd7ba65SCheng C Yang                                                     .get_ptr<uint64_t*>();
3615fd7ba65SCheng C Yang                                             if (preValue == nullptr)
3625fd7ba65SCheng C Yang                                             {
3635fd7ba65SCheng C Yang                                                 continue;
3645fd7ba65SCheng C Yang                                             }
365*0fda0f12SGeorge Liu                                             aResp->res.jsonValue
366*0fda0f12SGeorge Liu                                                 ["MemorySummary"]
367*0fda0f12SGeorge Liu                                                 ["TotalSystemMemoryGiB"] =
3685fd7ba65SCheng C Yang                                                 *value / (1024 * 1024) +
3695fd7ba65SCheng C Yang                                                 *preValue;
3705fd7ba65SCheng C Yang                                             aResp->res
3715fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
3729d3ae10eSAlpana Kumari                                                           ["Status"]["State"] =
3731abe55efSEd Tanous                                                 "Enabled";
374c5b2abe0SLewanczyk, Dawid                                         }
375c5b2abe0SLewanczyk, Dawid                                     }
3769d3ae10eSAlpana Kumari                                     else
3779d3ae10eSAlpana Kumari                                     {
3789d3ae10eSAlpana Kumari                                         auto getDimmProperties =
3799d3ae10eSAlpana Kumari                                             [aResp](
3809d3ae10eSAlpana Kumari                                                 const boost::system::error_code
381cb13a392SEd Tanous                                                     ec3,
3821214b7e7SGunnar Mills                                                 const std::variant<bool>&
3831214b7e7SGunnar Mills                                                     dimmState) {
384cb13a392SEd Tanous                                                 if (ec3)
3859d3ae10eSAlpana Kumari                                                 {
3869d3ae10eSAlpana Kumari                                                     BMCWEB_LOG_ERROR
387*0fda0f12SGeorge Liu                                                         << "DBUS response error "
388cb13a392SEd Tanous                                                         << ec3;
3899d3ae10eSAlpana Kumari                                                     return;
3909d3ae10eSAlpana Kumari                                                 }
3919d3ae10eSAlpana Kumari                                                 updateDimmProperties(aResp,
3929d3ae10eSAlpana Kumari                                                                      dimmState);
3939d3ae10eSAlpana Kumari                                             };
3949d3ae10eSAlpana Kumari                                         crow::connections::systemBus
3959d3ae10eSAlpana Kumari                                             ->async_method_call(
3969d3ae10eSAlpana Kumari                                                 std::move(getDimmProperties),
3979d3ae10eSAlpana Kumari                                                 service, path,
398*0fda0f12SGeorge Liu                                                 "org.freedesktop.DBus.Properties",
3999d3ae10eSAlpana Kumari                                                 "Get",
400*0fda0f12SGeorge Liu                                                 "xyz.openbmc_project.State.Decorator.OperationalStatus",
4019d3ae10eSAlpana Kumari                                                 "Functional");
4029d3ae10eSAlpana Kumari                                     }
403c5b2abe0SLewanczyk, Dawid                                 },
40404a258f4SEd Tanous                                 connection.first, path,
4056c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4066c34de48SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm");
4075bc2dc8eSJames Feist 
4085bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
4091abe55efSEd Tanous                         }
41004a258f4SEd Tanous                         else if (interfaceName ==
41104a258f4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.Cpu")
4121abe55efSEd Tanous                         {
4131abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
41404a258f4SEd Tanous                                 << "Found Cpu, now get its properties.";
41557e8c9beSAlpana Kumari 
41603fbed92SAli Ahmed                             getProcessorSummary(aResp, connection.first, path);
4175bc2dc8eSJames Feist 
4185bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
4191abe55efSEd Tanous                         }
42004a258f4SEd Tanous                         else if (interfaceName ==
42104a258f4SEd Tanous                                  "xyz.openbmc_project.Common.UUID")
4221abe55efSEd Tanous                         {
4231abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
42404a258f4SEd Tanous                                 << "Found UUID, now get its properties.";
42555c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
4261214b7e7SGunnar Mills                                 [aResp](
427cb13a392SEd Tanous                                     const boost::system::error_code ec3,
4286c34de48SEd Tanous                                     const std::vector<
4291214b7e7SGunnar Mills                                         std::pair<std::string, VariantType>>&
4301214b7e7SGunnar Mills                                         properties) {
431cb13a392SEd Tanous                                     if (ec3)
4321abe55efSEd Tanous                                     {
4331abe55efSEd Tanous                                         BMCWEB_LOG_DEBUG
434cb13a392SEd Tanous                                             << "DBUS response error " << ec3;
435f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
436c5b2abe0SLewanczyk, Dawid                                         return;
437c5b2abe0SLewanczyk, Dawid                                     }
4386c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
4396c34de48SEd Tanous                                                      << properties.size()
440c5b2abe0SLewanczyk, Dawid                                                      << " UUID properties.";
4411abe55efSEd Tanous                                     for (const std::pair<std::string,
4421214b7e7SGunnar Mills                                                          VariantType>&
4431214b7e7SGunnar Mills                                              property : properties)
4441abe55efSEd Tanous                                     {
44504a258f4SEd Tanous                                         if (property.first == "UUID")
4461abe55efSEd Tanous                                         {
447c5b2abe0SLewanczyk, Dawid                                             const std::string* value =
4488d78b7a9SPatrick Williams                                                 std::get_if<std::string>(
4491b6b96c5SEd Tanous                                                     &property.second);
45004a258f4SEd Tanous 
4511abe55efSEd Tanous                                             if (value != nullptr)
4521abe55efSEd Tanous                                             {
453029573d4SEd Tanous                                                 std::string valueStr = *value;
45404a258f4SEd Tanous                                                 if (valueStr.size() == 32)
4551abe55efSEd Tanous                                                 {
456029573d4SEd Tanous                                                     valueStr.insert(8, 1, '-');
457029573d4SEd Tanous                                                     valueStr.insert(13, 1, '-');
458029573d4SEd Tanous                                                     valueStr.insert(18, 1, '-');
459029573d4SEd Tanous                                                     valueStr.insert(23, 1, '-');
46004a258f4SEd Tanous                                                 }
461029573d4SEd Tanous                                                 BMCWEB_LOG_DEBUG << "UUID = "
46204a258f4SEd Tanous                                                                  << valueStr;
463029573d4SEd Tanous                                                 aResp->res.jsonValue["UUID"] =
46404a258f4SEd Tanous                                                     valueStr;
465c5b2abe0SLewanczyk, Dawid                                             }
466c5b2abe0SLewanczyk, Dawid                                         }
467c5b2abe0SLewanczyk, Dawid                                     }
468c5b2abe0SLewanczyk, Dawid                                 },
46904a258f4SEd Tanous                                 connection.first, path,
4706c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4711abe55efSEd Tanous                                 "xyz.openbmc_project.Common.UUID");
472c5b2abe0SLewanczyk, Dawid                         }
473029573d4SEd Tanous                         else if (interfaceName ==
474029573d4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.System")
4751abe55efSEd Tanous                         {
476029573d4SEd Tanous                             crow::connections::systemBus->async_method_call(
4771214b7e7SGunnar Mills                                 [aResp](
478cb13a392SEd Tanous                                     const boost::system::error_code ec2,
479029573d4SEd Tanous                                     const std::vector<
4801214b7e7SGunnar Mills                                         std::pair<std::string, VariantType>>&
4811214b7e7SGunnar Mills                                         propertiesList) {
482cb13a392SEd Tanous                                     if (ec2)
483029573d4SEd Tanous                                     {
484e4a4b9a9SJames Feist                                         // doesn't have to include this
485e4a4b9a9SJames Feist                                         // interface
486029573d4SEd Tanous                                         return;
487029573d4SEd Tanous                                     }
488698654b6SGunnar Mills                                     BMCWEB_LOG_DEBUG
489698654b6SGunnar Mills                                         << "Got " << propertiesList.size()
490029573d4SEd Tanous                                         << " properties for system";
491029573d4SEd Tanous                                     for (const std::pair<std::string,
4921214b7e7SGunnar Mills                                                          VariantType>&
4931214b7e7SGunnar Mills                                              property : propertiesList)
494029573d4SEd Tanous                                     {
495fc5afcf9Sbeccabroek                                         const std::string& propertyName =
496fc5afcf9Sbeccabroek                                             property.first;
497fc5afcf9Sbeccabroek                                         if ((propertyName == "PartNumber") ||
498fc5afcf9Sbeccabroek                                             (propertyName == "SerialNumber") ||
499fc5afcf9Sbeccabroek                                             (propertyName == "Manufacturer") ||
5005235d964SSunnySrivastava1984                                             (propertyName == "Model") ||
5015235d964SSunnySrivastava1984                                             (propertyName == "SubModel"))
502fc5afcf9Sbeccabroek                                         {
503029573d4SEd Tanous                                             const std::string* value =
504fc5afcf9Sbeccabroek                                                 std::get_if<std::string>(
505029573d4SEd Tanous                                                     &property.second);
506029573d4SEd Tanous                                             if (value != nullptr)
507029573d4SEd Tanous                                             {
508029573d4SEd Tanous                                                 aResp->res
509fc5afcf9Sbeccabroek                                                     .jsonValue[propertyName] =
510029573d4SEd Tanous                                                     *value;
511029573d4SEd Tanous                                             }
512029573d4SEd Tanous                                         }
513fc5afcf9Sbeccabroek                                     }
514c1e236a6SGunnar Mills 
515cb7e1e7bSAndrew Geissler                                     // Grab the bios version
516f97ddba7SGunnar Mills                                     fw_util::populateFirmwareInformation(
517cb7e1e7bSAndrew Geissler                                         aResp, fw_util::biosPurpose,
51872d566d9SGunnar Mills                                         "BiosVersion", false);
519029573d4SEd Tanous                                 },
520029573d4SEd Tanous                                 connection.first, path,
521029573d4SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
522*0fda0f12SGeorge Liu                                 "xyz.openbmc_project.Inventory.Decorator.Asset");
523e4a4b9a9SJames Feist 
524e4a4b9a9SJames Feist                             crow::connections::systemBus->async_method_call(
525e4a4b9a9SJames Feist                                 [aResp](
526cb13a392SEd Tanous                                     const boost::system::error_code ec2,
527e4a4b9a9SJames Feist                                     const std::variant<std::string>& property) {
528cb13a392SEd Tanous                                     if (ec2)
529e4a4b9a9SJames Feist                                     {
530e4a4b9a9SJames Feist                                         // doesn't have to include this
531e4a4b9a9SJames Feist                                         // interface
532e4a4b9a9SJames Feist                                         return;
533e4a4b9a9SJames Feist                                     }
534e4a4b9a9SJames Feist 
535e4a4b9a9SJames Feist                                     const std::string* value =
536e4a4b9a9SJames Feist                                         std::get_if<std::string>(&property);
537e4a4b9a9SJames Feist                                     if (value != nullptr)
538e4a4b9a9SJames Feist                                     {
539e4a4b9a9SJames Feist                                         aResp->res.jsonValue["AssetTag"] =
540e4a4b9a9SJames Feist                                             *value;
541e4a4b9a9SJames Feist                                     }
542e4a4b9a9SJames Feist                                 },
543e4a4b9a9SJames Feist                                 connection.first, path,
544e4a4b9a9SJames Feist                                 "org.freedesktop.DBus.Properties", "Get",
545*0fda0f12SGeorge Liu                                 "xyz.openbmc_project.Inventory.Decorator.AssetTag",
546e4a4b9a9SJames Feist                                 "AssetTag");
547029573d4SEd Tanous                         }
548029573d4SEd Tanous                     }
549029573d4SEd Tanous                 }
550c5b2abe0SLewanczyk, Dawid             }
551c5b2abe0SLewanczyk, Dawid         },
552c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
553c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
554c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5556617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
5566617338dSEd Tanous         std::array<const char*, 5>{
5576617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
5586617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
5596617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
5606617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
5616617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
5626617338dSEd Tanous         });
563c5b2abe0SLewanczyk, Dawid }
564c5b2abe0SLewanczyk, Dawid 
565c5b2abe0SLewanczyk, Dawid /**
566c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
567c5b2abe0SLewanczyk, Dawid  *
568c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
569c5b2abe0SLewanczyk, Dawid  *
570c5b2abe0SLewanczyk, Dawid  * @return None.
571c5b2abe0SLewanczyk, Dawid  */
5728d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5731abe55efSEd Tanous {
57455c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
57555c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
576c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
577abf2add6SEd Tanous                 const std::variant<std::string>& hostState) {
5781abe55efSEd Tanous             if (ec)
5791abe55efSEd Tanous             {
58055c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
581f12894f8SJason M. Bills                 messages::internalError(aResp->res);
582c5b2abe0SLewanczyk, Dawid                 return;
583c5b2abe0SLewanczyk, Dawid             }
5846617338dSEd Tanous 
585abf2add6SEd Tanous             const std::string* s = std::get_if<std::string>(&hostState);
58655c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Host state: " << *s;
5876617338dSEd Tanous             if (s != nullptr)
5881abe55efSEd Tanous             {
589c5b2abe0SLewanczyk, Dawid                 // Verify Host State
59094732661SAndrew Geissler                 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
5911abe55efSEd Tanous                 {
59255c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "On";
5936617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Enabled";
5941abe55efSEd Tanous                 }
595*0fda0f12SGeorge Liu                 else if (*s ==
596*0fda0f12SGeorge Liu                          "xyz.openbmc_project.State.Host.HostState.Quiesced")
5978c888608SGunnar Mills                 {
5988c888608SGunnar Mills                     aResp->res.jsonValue["PowerState"] = "On";
5998c888608SGunnar Mills                     aResp->res.jsonValue["Status"]["State"] = "Quiesced";
6008c888608SGunnar Mills                 }
601*0fda0f12SGeorge Liu                 else if (
602*0fda0f12SGeorge Liu                     *s ==
603*0fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
60483935af9SAndrew Geissler                 {
60583935af9SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "On";
60683935af9SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "InTest";
60783935af9SAndrew Geissler                 }
608*0fda0f12SGeorge Liu                 else if (
609*0fda0f12SGeorge Liu                     *s ==
610*0fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6111a2a1437SAndrew Geissler                 {
6121a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOn";
61315c27bf8SNoah Brewer                     aResp->res.jsonValue["Status"]["State"] = "Starting";
6141a2a1437SAndrew Geissler                 }
615*0fda0f12SGeorge Liu                 else if (
616*0fda0f12SGeorge Liu                     *s ==
617*0fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6181a2a1437SAndrew Geissler                 {
6191a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOff";
6201a2a1437SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
6211a2a1437SAndrew Geissler                 }
6221abe55efSEd Tanous                 else
6231abe55efSEd Tanous                 {
62455c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "Off";
6256617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
626c5b2abe0SLewanczyk, Dawid                 }
627c5b2abe0SLewanczyk, Dawid             }
628c5b2abe0SLewanczyk, Dawid         },
6296c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
6306617338dSEd Tanous         "org.freedesktop.DBus.Properties", "Get",
6316617338dSEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState");
632c5b2abe0SLewanczyk, Dawid }
633c5b2abe0SLewanczyk, Dawid 
634c5b2abe0SLewanczyk, Dawid /**
635786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
636491d8ee7SSantosh Puranik  *
637491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
638491d8ee7SSantosh Puranik  *
639491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
640491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
641491d8ee7SSantosh Puranik  */
64223a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
643491d8ee7SSantosh Puranik {
644491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
645491d8ee7SSantosh Puranik     {
646491d8ee7SSantosh Puranik         return "None";
647491d8ee7SSantosh Puranik     }
6483174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
649491d8ee7SSantosh Puranik     {
650491d8ee7SSantosh Puranik         return "Hdd";
651491d8ee7SSantosh Puranik     }
6523174e4dfSEd Tanous     if (dbusSource ==
653a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
654491d8ee7SSantosh Puranik     {
655491d8ee7SSantosh Puranik         return "Cd";
656491d8ee7SSantosh Puranik     }
6573174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
658491d8ee7SSantosh Puranik     {
659491d8ee7SSantosh Puranik         return "Pxe";
660491d8ee7SSantosh Puranik     }
6613174e4dfSEd Tanous     if (dbusSource ==
662944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6639f16b2c1SJennifer Lee     {
6649f16b2c1SJennifer Lee         return "Usb";
6659f16b2c1SJennifer Lee     }
666491d8ee7SSantosh Puranik     return "";
667491d8ee7SSantosh Puranik }
668491d8ee7SSantosh Puranik 
669491d8ee7SSantosh Puranik /**
670cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
671cd9a4666SKonstantin Aladyshev  *
672cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
673cd9a4666SKonstantin Aladyshev  *
674cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
675cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
676cd9a4666SKonstantin Aladyshev  */
677cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
678cd9a4666SKonstantin Aladyshev {
679cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
680cd9a4666SKonstantin Aladyshev     {
681cd9a4666SKonstantin Aladyshev         return "Legacy";
682cd9a4666SKonstantin Aladyshev     }
683cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
684cd9a4666SKonstantin Aladyshev     {
685cd9a4666SKonstantin Aladyshev         return "UEFI";
686cd9a4666SKonstantin Aladyshev     }
687cd9a4666SKonstantin Aladyshev     return "";
688cd9a4666SKonstantin Aladyshev }
689cd9a4666SKonstantin Aladyshev 
690cd9a4666SKonstantin Aladyshev /**
691786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
692491d8ee7SSantosh Puranik  *
693491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
694491d8ee7SSantosh Puranik  *
695491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
696491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
697491d8ee7SSantosh Puranik  */
69823a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
699491d8ee7SSantosh Puranik {
700491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
701491d8ee7SSantosh Puranik     {
702491d8ee7SSantosh Puranik         return "None";
703491d8ee7SSantosh Puranik     }
7043174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
705491d8ee7SSantosh Puranik     {
706491d8ee7SSantosh Puranik         return "Diags";
707491d8ee7SSantosh Puranik     }
7083174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
709491d8ee7SSantosh Puranik     {
710491d8ee7SSantosh Puranik         return "BiosSetup";
711491d8ee7SSantosh Puranik     }
712491d8ee7SSantosh Puranik     return "";
713491d8ee7SSantosh Puranik }
714491d8ee7SSantosh Puranik 
715491d8ee7SSantosh Puranik /**
716786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
717491d8ee7SSantosh Puranik  *
718491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
719944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
720944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
721491d8ee7SSantosh Puranik  *
722944ffaf9SJohnathan Mantey  * @return Integer error code.
723491d8ee7SSantosh Puranik  */
7248d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
725944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
726944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
727491d8ee7SSantosh Puranik {
728c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
729c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
730944ffaf9SJohnathan Mantey 
731491d8ee7SSantosh Puranik     if (rfSource == "None")
732491d8ee7SSantosh Puranik     {
733944ffaf9SJohnathan Mantey         return 0;
734491d8ee7SSantosh Puranik     }
7353174e4dfSEd Tanous     if (rfSource == "Pxe")
736491d8ee7SSantosh Puranik     {
737944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
738944ffaf9SJohnathan Mantey     }
739944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
740944ffaf9SJohnathan Mantey     {
741944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
742944ffaf9SJohnathan Mantey     }
743944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
744944ffaf9SJohnathan Mantey     {
745944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
746944ffaf9SJohnathan Mantey     }
747944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
748944ffaf9SJohnathan Mantey     {
749944ffaf9SJohnathan Mantey         bootSource =
750944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
751944ffaf9SJohnathan Mantey     }
752944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
753944ffaf9SJohnathan Mantey     {
754944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
755491d8ee7SSantosh Puranik     }
7569f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7579f16b2c1SJennifer Lee     {
758944ffaf9SJohnathan Mantey         bootSource =
759944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
7609f16b2c1SJennifer Lee     }
761491d8ee7SSantosh Puranik     else
762491d8ee7SSantosh Puranik     {
763*0fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
764*0fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
765944ffaf9SJohnathan Mantey             << bootSource;
766944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
767944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
768944ffaf9SJohnathan Mantey         return -1;
769491d8ee7SSantosh Puranik     }
770944ffaf9SJohnathan Mantey     return 0;
771491d8ee7SSantosh Puranik }
7721981771bSAli Ahmed 
773978b8803SAndrew Geissler /**
774978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
775978b8803SAndrew Geissler  *
776978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
777978b8803SAndrew Geissler  *
778978b8803SAndrew Geissler  * @return None.
779978b8803SAndrew Geissler  */
7808d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
781978b8803SAndrew Geissler {
782978b8803SAndrew Geissler     crow::connections::systemBus->async_method_call(
783978b8803SAndrew Geissler         [aResp](const boost::system::error_code ec,
784978b8803SAndrew Geissler                 const std::variant<std::string>& bootProgress) {
785978b8803SAndrew Geissler             if (ec)
786978b8803SAndrew Geissler             {
787978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
788978b8803SAndrew Geissler                 // not found
789978b8803SAndrew Geissler                 return;
790978b8803SAndrew Geissler             }
791978b8803SAndrew Geissler 
792978b8803SAndrew Geissler             const std::string* bootProgressStr =
793978b8803SAndrew Geissler                 std::get_if<std::string>(&bootProgress);
794978b8803SAndrew Geissler 
795978b8803SAndrew Geissler             if (!bootProgressStr)
796978b8803SAndrew Geissler             {
797978b8803SAndrew Geissler                 // Interface implemented but property not found, return error
798978b8803SAndrew Geissler                 // for that
799978b8803SAndrew Geissler                 messages::internalError(aResp->res);
800978b8803SAndrew Geissler                 return;
801978b8803SAndrew Geissler             }
802978b8803SAndrew Geissler 
803978b8803SAndrew Geissler             BMCWEB_LOG_DEBUG << "Boot Progress: " << *bootProgressStr;
804978b8803SAndrew Geissler 
805978b8803SAndrew Geissler             // Now convert the D-Bus BootProgress to the appropriate Redfish
806978b8803SAndrew Geissler             // enum
807978b8803SAndrew Geissler             std::string rfBpLastState = "None";
808*0fda0f12SGeorge Liu             if (*bootProgressStr ==
809*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified")
810978b8803SAndrew Geissler             {
811978b8803SAndrew Geissler                 rfBpLastState = "None";
812978b8803SAndrew Geissler             }
813*0fda0f12SGeorge Liu             else if (
814*0fda0f12SGeorge Liu                 *bootProgressStr ==
815*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.PrimaryProcInit")
816978b8803SAndrew Geissler             {
817978b8803SAndrew Geissler                 rfBpLastState = "PrimaryProcessorInitializationStarted";
818978b8803SAndrew Geissler             }
819*0fda0f12SGeorge Liu             else if (
820*0fda0f12SGeorge Liu                 *bootProgressStr ==
821*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.BusInit")
822978b8803SAndrew Geissler             {
823978b8803SAndrew Geissler                 rfBpLastState = "BusInitializationStarted";
824978b8803SAndrew Geissler             }
825*0fda0f12SGeorge Liu             else if (
826*0fda0f12SGeorge Liu                 *bootProgressStr ==
827*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MemoryInit")
828978b8803SAndrew Geissler             {
829978b8803SAndrew Geissler                 rfBpLastState = "MemoryInitializationStarted";
830978b8803SAndrew Geissler             }
831*0fda0f12SGeorge Liu             else if (
832*0fda0f12SGeorge Liu                 *bootProgressStr ==
833*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.SecondaryProcInit")
834978b8803SAndrew Geissler             {
835978b8803SAndrew Geissler                 rfBpLastState = "SecondaryProcessorInitializationStarted";
836978b8803SAndrew Geissler             }
837*0fda0f12SGeorge Liu             else if (
838*0fda0f12SGeorge Liu                 *bootProgressStr ==
839*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.PCIInit")
840978b8803SAndrew Geissler             {
841978b8803SAndrew Geissler                 rfBpLastState = "PCIResourceConfigStarted";
842978b8803SAndrew Geissler             }
843*0fda0f12SGeorge Liu             else if (
844*0fda0f12SGeorge Liu                 *bootProgressStr ==
845*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.SystemInitComplete")
846978b8803SAndrew Geissler             {
847978b8803SAndrew Geissler                 rfBpLastState = "SystemHardwareInitializationComplete";
848978b8803SAndrew Geissler             }
849*0fda0f12SGeorge Liu             else if (
850*0fda0f12SGeorge Liu                 *bootProgressStr ==
851*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart")
852978b8803SAndrew Geissler             {
853978b8803SAndrew Geissler                 rfBpLastState = "OSBootStarted";
854978b8803SAndrew Geissler             }
855*0fda0f12SGeorge Liu             else if (
856*0fda0f12SGeorge Liu                 *bootProgressStr ==
857*0fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSRunning")
858978b8803SAndrew Geissler             {
859978b8803SAndrew Geissler                 rfBpLastState = "OSRunning";
860978b8803SAndrew Geissler             }
861978b8803SAndrew Geissler             else
862978b8803SAndrew Geissler             {
863978b8803SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
864978b8803SAndrew Geissler                                  << *bootProgressStr;
865978b8803SAndrew Geissler                 // Just return the default
866978b8803SAndrew Geissler             }
867978b8803SAndrew Geissler 
868978b8803SAndrew Geissler             aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState;
869978b8803SAndrew Geissler         },
870978b8803SAndrew Geissler         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
871978b8803SAndrew Geissler         "org.freedesktop.DBus.Properties", "Get",
872978b8803SAndrew Geissler         "xyz.openbmc_project.State.Boot.Progress", "BootProgress");
873978b8803SAndrew Geissler }
874491d8ee7SSantosh Puranik 
875491d8ee7SSantosh Puranik /**
876c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
877cd9a4666SKonstantin Aladyshev  *
878cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
879cd9a4666SKonstantin Aladyshev  *
880cd9a4666SKonstantin Aladyshev  * @return None.
881cd9a4666SKonstantin Aladyshev  */
882cd9a4666SKonstantin Aladyshev 
883c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
884cd9a4666SKonstantin Aladyshev {
885cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
886cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
887cd9a4666SKonstantin Aladyshev                 const std::variant<std::string>& bootType) {
888cd9a4666SKonstantin Aladyshev             if (ec)
889cd9a4666SKonstantin Aladyshev             {
890cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
891cd9a4666SKonstantin Aladyshev                 return;
892cd9a4666SKonstantin Aladyshev             }
893cd9a4666SKonstantin Aladyshev 
894cd9a4666SKonstantin Aladyshev             const std::string* bootTypeStr =
895cd9a4666SKonstantin Aladyshev                 std::get_if<std::string>(&bootType);
896cd9a4666SKonstantin Aladyshev 
897cd9a4666SKonstantin Aladyshev             if (!bootTypeStr)
898cd9a4666SKonstantin Aladyshev             {
899cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
900cd9a4666SKonstantin Aladyshev                 return;
901cd9a4666SKonstantin Aladyshev             }
902cd9a4666SKonstantin Aladyshev 
903cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type: " << *bootTypeStr;
904cd9a4666SKonstantin Aladyshev 
905*0fda0f12SGeorge Liu             aResp->res
906*0fda0f12SGeorge Liu                 .jsonValue["Boot"]
907*0fda0f12SGeorge Liu                           ["BootSourceOverrideMode@Redfish.AllowableValues"] = {
908*0fda0f12SGeorge Liu                 "Legacy", "UEFI"};
909cd9a4666SKonstantin Aladyshev 
910cd9a4666SKonstantin Aladyshev             auto rfType = dbusToRfBootType(*bootTypeStr);
911cd9a4666SKonstantin Aladyshev             if (rfType.empty())
912cd9a4666SKonstantin Aladyshev             {
913cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
914cd9a4666SKonstantin Aladyshev                 return;
915cd9a4666SKonstantin Aladyshev             }
916cd9a4666SKonstantin Aladyshev 
917cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
918cd9a4666SKonstantin Aladyshev         },
919c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
920c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
921cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
922cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType");
923cd9a4666SKonstantin Aladyshev }
924cd9a4666SKonstantin Aladyshev 
925cd9a4666SKonstantin Aladyshev /**
926c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
927491d8ee7SSantosh Puranik  *
928491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
929491d8ee7SSantosh Puranik  *
930491d8ee7SSantosh Puranik  * @return None.
931491d8ee7SSantosh Puranik  */
932c21865c4SKonstantin Aladyshev 
933c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
934491d8ee7SSantosh Puranik {
935491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
936c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
937491d8ee7SSantosh Puranik                 const std::variant<std::string>& bootMode) {
938491d8ee7SSantosh Puranik             if (ec)
939491d8ee7SSantosh Puranik             {
940491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
941491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
942491d8ee7SSantosh Puranik                 return;
943491d8ee7SSantosh Puranik             }
944491d8ee7SSantosh Puranik 
945491d8ee7SSantosh Puranik             const std::string* bootModeStr =
946491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootMode);
947491d8ee7SSantosh Puranik 
948491d8ee7SSantosh Puranik             if (!bootModeStr)
949491d8ee7SSantosh Puranik             {
950491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
951491d8ee7SSantosh Puranik                 return;
952491d8ee7SSantosh Puranik             }
953491d8ee7SSantosh Puranik 
954491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
955491d8ee7SSantosh Puranik 
956*0fda0f12SGeorge Liu             aResp->res
957*0fda0f12SGeorge Liu                 .jsonValue["Boot"]
958*0fda0f12SGeorge Liu                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
959*0fda0f12SGeorge Liu                 {"None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
960491d8ee7SSantosh Puranik 
961491d8ee7SSantosh Puranik             if (*bootModeStr !=
962491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
963491d8ee7SSantosh Puranik             {
964491d8ee7SSantosh Puranik                 auto rfMode = dbusToRfBootMode(*bootModeStr);
965491d8ee7SSantosh Puranik                 if (!rfMode.empty())
966491d8ee7SSantosh Puranik                 {
967491d8ee7SSantosh Puranik                     aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
968491d8ee7SSantosh Puranik                         rfMode;
969491d8ee7SSantosh Puranik                 }
970491d8ee7SSantosh Puranik             }
971491d8ee7SSantosh Puranik         },
972c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
973c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
974491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
975491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
976491d8ee7SSantosh Puranik }
977491d8ee7SSantosh Puranik 
978491d8ee7SSantosh Puranik /**
979c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
980491d8ee7SSantosh Puranik  *
981491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
982491d8ee7SSantosh Puranik  *
983491d8ee7SSantosh Puranik  * @return None.
984491d8ee7SSantosh Puranik  */
985c21865c4SKonstantin Aladyshev 
986c21865c4SKonstantin Aladyshev inline void
987c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
988491d8ee7SSantosh Puranik {
989491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
990c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
991491d8ee7SSantosh Puranik                 const std::variant<std::string>& bootSource) {
992491d8ee7SSantosh Puranik             if (ec)
993491d8ee7SSantosh Puranik             {
994491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
995491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
996491d8ee7SSantosh Puranik                 return;
997491d8ee7SSantosh Puranik             }
998491d8ee7SSantosh Puranik 
999491d8ee7SSantosh Puranik             const std::string* bootSourceStr =
1000491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootSource);
1001491d8ee7SSantosh Puranik 
1002491d8ee7SSantosh Puranik             if (!bootSourceStr)
1003491d8ee7SSantosh Puranik             {
1004491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1005491d8ee7SSantosh Puranik                 return;
1006491d8ee7SSantosh Puranik             }
1007491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
1008491d8ee7SSantosh Puranik 
1009491d8ee7SSantosh Puranik             auto rfSource = dbusToRfBootSource(*bootSourceStr);
1010491d8ee7SSantosh Puranik             if (!rfSource.empty())
1011491d8ee7SSantosh Puranik             {
1012491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1013491d8ee7SSantosh Puranik                     rfSource;
1014491d8ee7SSantosh Puranik             }
1015cd9a4666SKonstantin Aladyshev 
1016cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1017cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
1018c21865c4SKonstantin Aladyshev             getBootOverrideMode(aResp);
1019491d8ee7SSantosh Puranik         },
1020c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1021c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1022491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1023491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource");
1024491d8ee7SSantosh Puranik }
1025491d8ee7SSantosh Puranik 
1026491d8ee7SSantosh Puranik /**
1027c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1028c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1029c21865c4SKonstantin Aladyshev  * state
1030491d8ee7SSantosh Puranik  *
1031491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1032491d8ee7SSantosh Puranik  *
1033491d8ee7SSantosh Puranik  * @return None.
1034491d8ee7SSantosh Puranik  */
1035491d8ee7SSantosh Puranik 
1036c21865c4SKonstantin Aladyshev inline void
1037c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1038c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1039c21865c4SKonstantin Aladyshev {
1040c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1041c21865c4SKonstantin Aladyshev     {
1042c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1043c21865c4SKonstantin Aladyshev         return;
1044c21865c4SKonstantin Aladyshev     }
1045c21865c4SKonstantin Aladyshev 
1046c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1047c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1048491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1049c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
105019bd78d9SPatrick Williams                 const std::variant<bool>& oneTime) {
1051491d8ee7SSantosh Puranik             if (ec)
1052491d8ee7SSantosh Puranik             {
1053491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1054c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1055491d8ee7SSantosh Puranik                 return;
1056491d8ee7SSantosh Puranik             }
1057491d8ee7SSantosh Puranik 
1058491d8ee7SSantosh Puranik             const bool* oneTimePtr = std::get_if<bool>(&oneTime);
1059491d8ee7SSantosh Puranik 
1060491d8ee7SSantosh Puranik             if (!oneTimePtr)
1061491d8ee7SSantosh Puranik             {
1062491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1063491d8ee7SSantosh Puranik                 return;
1064491d8ee7SSantosh Puranik             }
1065c21865c4SKonstantin Aladyshev 
1066c21865c4SKonstantin Aladyshev             bool oneTimeSetting = *oneTimePtr;
1067c21865c4SKonstantin Aladyshev 
1068c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1069c21865c4SKonstantin Aladyshev             {
1070c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1071c21865c4SKonstantin Aladyshev                     "Once";
1072c21865c4SKonstantin Aladyshev             }
1073c21865c4SKonstantin Aladyshev             else
1074c21865c4SKonstantin Aladyshev             {
1075c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1076c21865c4SKonstantin Aladyshev                     "Continuous";
1077c21865c4SKonstantin Aladyshev             }
1078491d8ee7SSantosh Puranik         },
1079491d8ee7SSantosh Puranik         "xyz.openbmc_project.Settings",
1080491d8ee7SSantosh Puranik         "/xyz/openbmc_project/control/host0/boot/one_time",
1081491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1082491d8ee7SSantosh Puranik         "xyz.openbmc_project.Object.Enable", "Enabled");
1083491d8ee7SSantosh Puranik }
1084491d8ee7SSantosh Puranik 
1085491d8ee7SSantosh Puranik /**
1086c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1087c21865c4SKonstantin Aladyshev  *
1088c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1089c21865c4SKonstantin Aladyshev  *
1090c21865c4SKonstantin Aladyshev  * @return None.
1091c21865c4SKonstantin Aladyshev  */
1092c21865c4SKonstantin Aladyshev 
1093c21865c4SKonstantin Aladyshev inline void
1094c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1095c21865c4SKonstantin Aladyshev {
1096c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1097c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
1098c21865c4SKonstantin Aladyshev                 const std::variant<bool>& bootOverrideEnable) {
1099c21865c4SKonstantin Aladyshev             if (ec)
1100c21865c4SKonstantin Aladyshev             {
1101c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1102c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1103c21865c4SKonstantin Aladyshev                 return;
1104c21865c4SKonstantin Aladyshev             }
1105c21865c4SKonstantin Aladyshev 
1106c21865c4SKonstantin Aladyshev             const bool* bootOverrideEnablePtr =
1107c21865c4SKonstantin Aladyshev                 std::get_if<bool>(&bootOverrideEnable);
1108c21865c4SKonstantin Aladyshev 
1109c21865c4SKonstantin Aladyshev             if (!bootOverrideEnablePtr)
1110c21865c4SKonstantin Aladyshev             {
1111c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1112c21865c4SKonstantin Aladyshev                 return;
1113c21865c4SKonstantin Aladyshev             }
1114c21865c4SKonstantin Aladyshev 
1115c21865c4SKonstantin Aladyshev             processBootOverrideEnable(aResp, *bootOverrideEnablePtr);
1116c21865c4SKonstantin Aladyshev         },
1117c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1118c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1119c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
1120c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled");
1121c21865c4SKonstantin Aladyshev }
1122c21865c4SKonstantin Aladyshev 
1123c21865c4SKonstantin Aladyshev /**
1124c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1125c21865c4SKonstantin Aladyshev  *
1126c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1127c21865c4SKonstantin Aladyshev  *
1128c21865c4SKonstantin Aladyshev  * @return None.
1129c21865c4SKonstantin Aladyshev  */
1130c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1131c21865c4SKonstantin Aladyshev {
1132c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1133c21865c4SKonstantin Aladyshev 
1134c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1135c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1136c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1137c21865c4SKonstantin Aladyshev }
1138c21865c4SKonstantin Aladyshev 
1139c21865c4SKonstantin Aladyshev /**
1140c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1141c0557e1aSGunnar Mills  *
1142c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1143c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1144c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1145c0557e1aSGunnar Mills  * last power operation time.
1146c0557e1aSGunnar Mills  *
1147c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1148c0557e1aSGunnar Mills  *
1149c0557e1aSGunnar Mills  * @return None.
1150c0557e1aSGunnar Mills  */
11518d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1152c0557e1aSGunnar Mills {
1153c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1154c0557e1aSGunnar Mills 
1155c0557e1aSGunnar Mills     crow::connections::systemBus->async_method_call(
1156c0557e1aSGunnar Mills         [aResp](const boost::system::error_code ec,
1157c0557e1aSGunnar Mills                 std::variant<uint64_t>& lastResetTime) {
1158c0557e1aSGunnar Mills             if (ec)
1159c0557e1aSGunnar Mills             {
1160c0557e1aSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1161c0557e1aSGunnar Mills                 return;
1162c0557e1aSGunnar Mills             }
1163c0557e1aSGunnar Mills 
1164c0557e1aSGunnar Mills             const uint64_t* lastResetTimePtr =
1165c0557e1aSGunnar Mills                 std::get_if<uint64_t>(&lastResetTime);
1166c0557e1aSGunnar Mills 
1167c0557e1aSGunnar Mills             if (!lastResetTimePtr)
1168c0557e1aSGunnar Mills             {
1169c0557e1aSGunnar Mills                 messages::internalError(aResp->res);
1170c0557e1aSGunnar Mills                 return;
1171c0557e1aSGunnar Mills             }
1172c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1173c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1174c0557e1aSGunnar Mills             time_t lastResetTimeStamp =
1175c0557e1aSGunnar Mills                 static_cast<time_t>(*lastResetTimePtr / 1000);
1176c0557e1aSGunnar Mills 
1177c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1178c0557e1aSGunnar Mills             aResp->res.jsonValue["LastResetTime"] =
1179c0557e1aSGunnar Mills                 crow::utility::getDateTime(lastResetTimeStamp);
1180c0557e1aSGunnar Mills         },
1181c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis",
1182c0557e1aSGunnar Mills         "/xyz/openbmc_project/state/chassis0",
1183c0557e1aSGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
1184c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
1185c0557e1aSGunnar Mills }
1186c0557e1aSGunnar Mills 
1187c0557e1aSGunnar Mills /**
11886bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11896bd5a8d2SGunnar Mills  *
11906bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11916bd5a8d2SGunnar Mills  *
11926bd5a8d2SGunnar Mills  * @return None.
11936bd5a8d2SGunnar Mills  */
11948d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11956bd5a8d2SGunnar Mills {
11966bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
11976bd5a8d2SGunnar Mills 
11986bd5a8d2SGunnar Mills     crow::connections::systemBus->async_method_call(
11996bd5a8d2SGunnar Mills         [aResp](const boost::system::error_code ec,
12006bd5a8d2SGunnar Mills                 std::variant<bool>& autoRebootEnabled) {
12016bd5a8d2SGunnar Mills             if (ec)
12026bd5a8d2SGunnar Mills             {
12036bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
12046bd5a8d2SGunnar Mills                 return;
12056bd5a8d2SGunnar Mills             }
12066bd5a8d2SGunnar Mills 
12076bd5a8d2SGunnar Mills             const bool* autoRebootEnabledPtr =
12086bd5a8d2SGunnar Mills                 std::get_if<bool>(&autoRebootEnabled);
12096bd5a8d2SGunnar Mills 
12106bd5a8d2SGunnar Mills             if (!autoRebootEnabledPtr)
12116bd5a8d2SGunnar Mills             {
12126bd5a8d2SGunnar Mills                 messages::internalError(aResp->res);
12136bd5a8d2SGunnar Mills                 return;
12146bd5a8d2SGunnar Mills             }
12156bd5a8d2SGunnar Mills 
12166bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
12176bd5a8d2SGunnar Mills             if (*autoRebootEnabledPtr == true)
12186bd5a8d2SGunnar Mills             {
12196bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12206bd5a8d2SGunnar Mills                     "RetryAttempts";
12216bd5a8d2SGunnar Mills                 // If AutomaticRetry (AutoReboot) is enabled see how many
12226bd5a8d2SGunnar Mills                 // attempts are left
12236bd5a8d2SGunnar Mills                 crow::connections::systemBus->async_method_call(
1224cb13a392SEd Tanous                     [aResp](const boost::system::error_code ec2,
12256bd5a8d2SGunnar Mills                             std::variant<uint32_t>& autoRebootAttemptsLeft) {
1226cb13a392SEd Tanous                         if (ec2)
12276bd5a8d2SGunnar Mills                         {
1228cb13a392SEd Tanous                             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
12296bd5a8d2SGunnar Mills                             return;
12306bd5a8d2SGunnar Mills                         }
12316bd5a8d2SGunnar Mills 
12326bd5a8d2SGunnar Mills                         const uint32_t* autoRebootAttemptsLeftPtr =
12336bd5a8d2SGunnar Mills                             std::get_if<uint32_t>(&autoRebootAttemptsLeft);
12346bd5a8d2SGunnar Mills 
12356bd5a8d2SGunnar Mills                         if (!autoRebootAttemptsLeftPtr)
12366bd5a8d2SGunnar Mills                         {
12376bd5a8d2SGunnar Mills                             messages::internalError(aResp->res);
12386bd5a8d2SGunnar Mills                             return;
12396bd5a8d2SGunnar Mills                         }
12406bd5a8d2SGunnar Mills 
12416bd5a8d2SGunnar Mills                         BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
12426bd5a8d2SGunnar Mills                                          << *autoRebootAttemptsLeftPtr;
12436bd5a8d2SGunnar Mills 
12446bd5a8d2SGunnar Mills                         aResp->res
12456bd5a8d2SGunnar Mills                             .jsonValue["Boot"]
12466bd5a8d2SGunnar Mills                                       ["RemainingAutomaticRetryAttempts"] =
12476bd5a8d2SGunnar Mills                             *autoRebootAttemptsLeftPtr;
12486bd5a8d2SGunnar Mills                     },
12496bd5a8d2SGunnar Mills                     "xyz.openbmc_project.State.Host",
12506bd5a8d2SGunnar Mills                     "/xyz/openbmc_project/state/host0",
12516bd5a8d2SGunnar Mills                     "org.freedesktop.DBus.Properties", "Get",
12526bd5a8d2SGunnar Mills                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
12536bd5a8d2SGunnar Mills                     "AttemptsLeft");
12546bd5a8d2SGunnar Mills             }
12556bd5a8d2SGunnar Mills             else
12566bd5a8d2SGunnar Mills             {
12576bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12586bd5a8d2SGunnar Mills                     "Disabled";
12596bd5a8d2SGunnar Mills             }
12606bd5a8d2SGunnar Mills 
12616bd5a8d2SGunnar Mills             // Not on D-Bus. Hardcoded here:
12626bd5a8d2SGunnar Mills             // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
12636bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
126469f35306SGunnar Mills 
126569f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
126669f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
126769f35306SGunnar Mills             // RetryAttempts.
1268*0fda0f12SGeorge Liu             aResp->res
1269*0fda0f12SGeorge Liu                 .jsonValue["Boot"]
1270*0fda0f12SGeorge Liu                           ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
1271*0fda0f12SGeorge Liu                 "Disabled", "RetryAttempts"};
12726bd5a8d2SGunnar Mills         },
12736bd5a8d2SGunnar Mills         "xyz.openbmc_project.Settings",
12746bd5a8d2SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
12756bd5a8d2SGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
12766bd5a8d2SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
12776bd5a8d2SGunnar Mills }
12786bd5a8d2SGunnar Mills 
12796bd5a8d2SGunnar Mills /**
1280c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1281c6a620f2SGeorge Liu  *
1282c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1283c6a620f2SGeorge Liu  *
1284c6a620f2SGeorge Liu  * @return None.
1285c6a620f2SGeorge Liu  */
12868d1b46d7Szhanghch05 inline void
12878d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1288c6a620f2SGeorge Liu {
1289c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1290c6a620f2SGeorge Liu 
1291c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1292c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec,
129319bd78d9SPatrick Williams                 std::variant<std::string>& policy) {
1294c6a620f2SGeorge Liu             if (ec)
1295c6a620f2SGeorge Liu             {
1296c6a620f2SGeorge Liu                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1297c6a620f2SGeorge Liu                 return;
1298c6a620f2SGeorge Liu             }
1299c6a620f2SGeorge Liu 
1300*0fda0f12SGeorge Liu             const boost::container::flat_map<std::string, std::string> policyMaps = {
1301*0fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1302c6a620f2SGeorge Liu                  "AlwaysOn"},
1303*0fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1304c6a620f2SGeorge Liu                  "AlwaysOff"},
1305*0fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1306c6a620f2SGeorge Liu                  "LastState"}};
1307c6a620f2SGeorge Liu 
1308c6a620f2SGeorge Liu             const std::string* policyPtr = std::get_if<std::string>(&policy);
1309c6a620f2SGeorge Liu 
1310c6a620f2SGeorge Liu             if (!policyPtr)
1311c6a620f2SGeorge Liu             {
1312c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1313c6a620f2SGeorge Liu                 return;
1314c6a620f2SGeorge Liu             }
1315c6a620f2SGeorge Liu 
1316c6a620f2SGeorge Liu             auto policyMapsIt = policyMaps.find(*policyPtr);
1317c6a620f2SGeorge Liu             if (policyMapsIt == policyMaps.end())
1318c6a620f2SGeorge Liu             {
1319c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1320c6a620f2SGeorge Liu                 return;
1321c6a620f2SGeorge Liu             }
1322c6a620f2SGeorge Liu 
1323c6a620f2SGeorge Liu             aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1324c6a620f2SGeorge Liu         },
1325c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1326c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1327c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Get",
1328c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy",
1329c6a620f2SGeorge Liu         "PowerRestorePolicy");
1330c6a620f2SGeorge Liu }
1331c6a620f2SGeorge Liu 
1332c6a620f2SGeorge Liu /**
13331981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13341981771bSAli Ahmed  * TPM is required for booting the host.
13351981771bSAli Ahmed  *
13361981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13371981771bSAli Ahmed  *
13381981771bSAli Ahmed  * @return None.
13391981771bSAli Ahmed  */
13401981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13411981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13421981771bSAli Ahmed {
13431981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
13441981771bSAli Ahmed 
13451981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
13461981771bSAli Ahmed         [aResp](
13471981771bSAli Ahmed             const boost::system::error_code ec,
13481981771bSAli Ahmed             std::vector<std::pair<
13491981771bSAli Ahmed                 std::string,
13501981771bSAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
13511981771bSAli Ahmed                 subtree) {
13521981771bSAli Ahmed             if (ec)
13531981771bSAli Ahmed             {
13541981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
13551981771bSAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
13561981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
13571981771bSAli Ahmed                 // error occurs
13581981771bSAli Ahmed                 return;
13591981771bSAli Ahmed             }
13601981771bSAli Ahmed             if (subtree.size() == 0)
13611981771bSAli Ahmed             {
13621981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
13631981771bSAli Ahmed                 // if there is no instance found
13641981771bSAli Ahmed                 return;
13651981771bSAli Ahmed             }
13661981771bSAli Ahmed 
13671981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
13681981771bSAli Ahmed             if (subtree.size() > 1)
13691981771bSAli Ahmed             {
13701981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
13711981771bSAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
13721981771bSAli Ahmed                     << subtree.size();
13731981771bSAli Ahmed                 // Throw an internal Error and return
13741981771bSAli Ahmed                 messages::internalError(aResp->res);
13751981771bSAli Ahmed                 return;
13761981771bSAli Ahmed             }
13771981771bSAli Ahmed 
13781981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
13791981771bSAli Ahmed             // field
13801981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13811981771bSAli Ahmed             {
13821981771bSAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13831981771bSAli Ahmed                 messages::internalError(aResp->res);
13841981771bSAli Ahmed                 return;
13851981771bSAli Ahmed             }
13861981771bSAli Ahmed 
13871981771bSAli Ahmed             const std::string& path = subtree[0].first;
13881981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
13891981771bSAli Ahmed 
13901981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
13911981771bSAli Ahmed             crow::connections::systemBus->async_method_call(
13921981771bSAli Ahmed                 [aResp](const boost::system::error_code ec,
13931981771bSAli Ahmed                         std::variant<bool>& tpmRequired) {
13941981771bSAli Ahmed                     if (ec)
13951981771bSAli Ahmed                     {
13961981771bSAli Ahmed                         BMCWEB_LOG_DEBUG
13971981771bSAli Ahmed                             << "D-BUS response error on TPM.Policy Get" << ec;
13981981771bSAli Ahmed                         messages::internalError(aResp->res);
13991981771bSAli Ahmed                         return;
14001981771bSAli Ahmed                     }
14011981771bSAli Ahmed 
14021981771bSAli Ahmed                     const bool* tpmRequiredVal =
14031981771bSAli Ahmed                         std::get_if<bool>(&tpmRequired);
14041981771bSAli Ahmed 
14051981771bSAli Ahmed                     if (!tpmRequiredVal)
14061981771bSAli Ahmed                     {
14071981771bSAli Ahmed                         messages::internalError(aResp->res);
14081981771bSAli Ahmed                         return;
14091981771bSAli Ahmed                     }
14101981771bSAli Ahmed 
14111981771bSAli Ahmed                     if (*tpmRequiredVal == true)
14121981771bSAli Ahmed                     {
14131981771bSAli Ahmed                         aResp->res
14141981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14151981771bSAli Ahmed                             "Required";
14161981771bSAli Ahmed                     }
14171981771bSAli Ahmed                     else
14181981771bSAli Ahmed                     {
14191981771bSAli Ahmed                         aResp->res
14201981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14211981771bSAli Ahmed                             "Disabled";
14221981771bSAli Ahmed                     }
14231981771bSAli Ahmed                 },
14241981771bSAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Get",
14251981771bSAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable");
14261981771bSAli Ahmed         },
14271981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
14281981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
14291981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
14301981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
14311981771bSAli Ahmed }
14321981771bSAli Ahmed 
14331981771bSAli Ahmed /**
14341c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14351c05dae3SAli Ahmed  * TPM is required for booting the host.
14361c05dae3SAli Ahmed  *
14371c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
14381c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14391c05dae3SAli Ahmed  *
14401c05dae3SAli Ahmed  * @return None.
14411c05dae3SAli Ahmed  */
14421c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
14431c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
14441c05dae3SAli Ahmed {
14451c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
14461c05dae3SAli Ahmed 
14471c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
14481c05dae3SAli Ahmed         [aResp, tpmRequired](
14491c05dae3SAli Ahmed             const boost::system::error_code ec,
14501c05dae3SAli Ahmed             std::vector<std::pair<
14511c05dae3SAli Ahmed                 std::string,
14521c05dae3SAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
14531c05dae3SAli Ahmed                 subtree) {
14541c05dae3SAli Ahmed             if (ec)
14551c05dae3SAli Ahmed             {
14561c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
14571c05dae3SAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
14581c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14591c05dae3SAli Ahmed                 return;
14601c05dae3SAli Ahmed             }
14611c05dae3SAli Ahmed             if (subtree.size() == 0)
14621c05dae3SAli Ahmed             {
14631c05dae3SAli Ahmed                 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
14641c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
14651c05dae3SAli Ahmed                 return;
14661c05dae3SAli Ahmed             }
14671c05dae3SAli Ahmed 
14681c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
14691c05dae3SAli Ahmed             if (subtree.size() > 1)
14701c05dae3SAli Ahmed             {
14711c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
14721c05dae3SAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
14731c05dae3SAli Ahmed                     << subtree.size();
14741c05dae3SAli Ahmed                 // Throw an internal Error and return
14751c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14761c05dae3SAli Ahmed                 return;
14771c05dae3SAli Ahmed             }
14781c05dae3SAli Ahmed 
14791c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
14801c05dae3SAli Ahmed             // field
14811c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14821c05dae3SAli Ahmed             {
14831c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14841c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14851c05dae3SAli Ahmed                 return;
14861c05dae3SAli Ahmed             }
14871c05dae3SAli Ahmed 
14881c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
14891c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
14901c05dae3SAli Ahmed 
14911c05dae3SAli Ahmed             if (serv.empty())
14921c05dae3SAli Ahmed             {
14931c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
14941c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14951c05dae3SAli Ahmed                 return;
14961c05dae3SAli Ahmed             }
14971c05dae3SAli Ahmed 
14981c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
14991c05dae3SAli Ahmed             crow::connections::systemBus->async_method_call(
15001c05dae3SAli Ahmed                 [aResp](const boost::system::error_code ec) {
15011c05dae3SAli Ahmed                     if (ec)
15021c05dae3SAli Ahmed                     {
1503*0fda0f12SGeorge Liu                         BMCWEB_LOG_DEBUG
1504*0fda0f12SGeorge Liu                             << "DBUS response error: Set TrustedModuleRequiredToBoot"
15051c05dae3SAli Ahmed                             << ec;
15061c05dae3SAli Ahmed                         messages::internalError(aResp->res);
15071c05dae3SAli Ahmed                         return;
15081c05dae3SAli Ahmed                     }
15091c05dae3SAli Ahmed                     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
15101c05dae3SAli Ahmed                 },
15111c05dae3SAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Set",
15121c05dae3SAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
15131c05dae3SAli Ahmed                 std::variant<bool>(tpmRequired));
15141c05dae3SAli Ahmed         },
15151c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
15161c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
15171c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
15181c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
15191c05dae3SAli Ahmed }
15201c05dae3SAli Ahmed 
15211c05dae3SAli Ahmed /**
1522491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1523491d8ee7SSantosh Puranik  *
1524491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1525cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1526cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1527cd9a4666SKonstantin Aladyshev  */
1528cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1529cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1530cd9a4666SKonstantin Aladyshev {
1531c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1532cd9a4666SKonstantin Aladyshev 
1533c21865c4SKonstantin Aladyshev     if (!bootType)
1534cd9a4666SKonstantin Aladyshev     {
1535c21865c4SKonstantin Aladyshev         return;
1536c21865c4SKonstantin Aladyshev     }
1537c21865c4SKonstantin Aladyshev 
1538cd9a4666SKonstantin Aladyshev     // Source target specified
1539cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1540cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1541cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1542cd9a4666SKonstantin Aladyshev     {
1543cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1544cd9a4666SKonstantin Aladyshev     }
1545cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1546cd9a4666SKonstantin Aladyshev     {
1547cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1548cd9a4666SKonstantin Aladyshev     }
1549cd9a4666SKonstantin Aladyshev     else
1550cd9a4666SKonstantin Aladyshev     {
1551cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1552cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1553cd9a4666SKonstantin Aladyshev                          << *bootType;
1554cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1555cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1556cd9a4666SKonstantin Aladyshev         return;
1557cd9a4666SKonstantin Aladyshev     }
1558cd9a4666SKonstantin Aladyshev 
1559cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1560cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1561cd9a4666SKonstantin Aladyshev 
1562cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1563c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1564cd9a4666SKonstantin Aladyshev             if (ec)
1565cd9a4666SKonstantin Aladyshev             {
1566cd9a4666SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1567cd9a4666SKonstantin Aladyshev                 if (ec.value() == boost::asio::error::host_unreachable)
1568cd9a4666SKonstantin Aladyshev                 {
1569cd9a4666SKonstantin Aladyshev                     messages::resourceNotFound(aResp->res, "Set", "BootType");
1570cd9a4666SKonstantin Aladyshev                     return;
1571cd9a4666SKonstantin Aladyshev                 }
1572cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
1573cd9a4666SKonstantin Aladyshev                 return;
1574cd9a4666SKonstantin Aladyshev             }
1575cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type update done.";
1576cd9a4666SKonstantin Aladyshev         },
1577c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1578c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1579cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1580cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1581cd9a4666SKonstantin Aladyshev         std::variant<std::string>(bootTypeStr));
1582cd9a4666SKonstantin Aladyshev }
1583cd9a4666SKonstantin Aladyshev 
1584cd9a4666SKonstantin Aladyshev /**
1585cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1586cd9a4666SKonstantin Aladyshev  *
1587cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1588c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1589c21865c4SKonstantin Aladyshev  * @return Integer error code.
1590c21865c4SKonstantin Aladyshev  */
1591c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1592c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1593c21865c4SKonstantin Aladyshev {
1594c21865c4SKonstantin Aladyshev     if (!bootEnable)
1595c21865c4SKonstantin Aladyshev     {
1596c21865c4SKonstantin Aladyshev         return;
1597c21865c4SKonstantin Aladyshev     }
1598c21865c4SKonstantin Aladyshev     // Source target specified
1599c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1600c21865c4SKonstantin Aladyshev 
1601c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1602c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1603c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1604c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1605c21865c4SKonstantin Aladyshev     {
1606c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1607c21865c4SKonstantin Aladyshev     }
1608c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1609c21865c4SKonstantin Aladyshev     {
1610c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1611c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1612c21865c4SKonstantin Aladyshev     }
1613c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1614c21865c4SKonstantin Aladyshev     {
1615c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1616c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1617c21865c4SKonstantin Aladyshev     }
1618c21865c4SKonstantin Aladyshev     else
1619c21865c4SKonstantin Aladyshev     {
1620*0fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
1621*0fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1622c21865c4SKonstantin Aladyshev             << *bootEnable;
1623c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1624c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1625c21865c4SKonstantin Aladyshev         return;
1626c21865c4SKonstantin Aladyshev     }
1627c21865c4SKonstantin Aladyshev 
1628c21865c4SKonstantin Aladyshev     // Act on validated parameters
1629c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1630c21865c4SKonstantin Aladyshev 
1631c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1632c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1633c21865c4SKonstantin Aladyshev             if (ec)
1634c21865c4SKonstantin Aladyshev             {
1635c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1636c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1637c21865c4SKonstantin Aladyshev                 return;
1638c21865c4SKonstantin Aladyshev             }
1639c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1640c21865c4SKonstantin Aladyshev         },
1641c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1642c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1643c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1644c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1645c21865c4SKonstantin Aladyshev         std::variant<bool>(bootOverrideEnable));
1646c21865c4SKonstantin Aladyshev 
1647c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1648c21865c4SKonstantin Aladyshev     {
1649c21865c4SKonstantin Aladyshev         return;
1650c21865c4SKonstantin Aladyshev     }
1651c21865c4SKonstantin Aladyshev 
1652c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1653c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1654c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1655c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1656c21865c4SKonstantin Aladyshev 
1657c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1658c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1659c21865c4SKonstantin Aladyshev             if (ec)
1660c21865c4SKonstantin Aladyshev             {
1661c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1662c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1663c21865c4SKonstantin Aladyshev                 return;
1664c21865c4SKonstantin Aladyshev             }
1665c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1666c21865c4SKonstantin Aladyshev         },
1667c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1668c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1669c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1670c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1671c21865c4SKonstantin Aladyshev         std::variant<bool>(!bootOverridePersistent));
1672c21865c4SKonstantin Aladyshev }
1673c21865c4SKonstantin Aladyshev 
1674c21865c4SKonstantin Aladyshev /**
1675c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1676c21865c4SKonstantin Aladyshev  *
1677c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1678491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1679491d8ee7SSantosh Puranik  *
1680265c1602SJohnathan Mantey  * @return Integer error code.
1681491d8ee7SSantosh Puranik  */
1682cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1683cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1684491d8ee7SSantosh Puranik {
1685c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1686c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1687944ffaf9SJohnathan Mantey 
1688c21865c4SKonstantin Aladyshev     if (!bootSource)
1689491d8ee7SSantosh Puranik     {
1690c21865c4SKonstantin Aladyshev         return;
1691c21865c4SKonstantin Aladyshev     }
1692c21865c4SKonstantin Aladyshev 
1693491d8ee7SSantosh Puranik     // Source target specified
1694491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1695491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1696c21865c4SKonstantin Aladyshev     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr))
1697491d8ee7SSantosh Puranik     {
1698944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1699944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1700491d8ee7SSantosh Puranik             << *bootSource;
1701491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1702491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1703491d8ee7SSantosh Puranik         return;
1704491d8ee7SSantosh Puranik     }
1705491d8ee7SSantosh Puranik 
1706944ffaf9SJohnathan Mantey     // Act on validated parameters
1707944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1708944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1709944ffaf9SJohnathan Mantey 
1710491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1711491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1712491d8ee7SSantosh Puranik             if (ec)
1713491d8ee7SSantosh Puranik             {
1714491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1715491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1716491d8ee7SSantosh Puranik                 return;
1717491d8ee7SSantosh Puranik             }
1718491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source update done.";
1719491d8ee7SSantosh Puranik         },
1720c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1721c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1722491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1723491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1724491d8ee7SSantosh Puranik         std::variant<std::string>(bootSourceStr));
1725944ffaf9SJohnathan Mantey 
1726491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1727491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1728491d8ee7SSantosh Puranik             if (ec)
1729491d8ee7SSantosh Puranik             {
1730491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1731491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1732491d8ee7SSantosh Puranik                 return;
1733491d8ee7SSantosh Puranik             }
1734491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode update done.";
1735491d8ee7SSantosh Puranik         },
1736c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1737c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1738491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1739491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1740491d8ee7SSantosh Puranik         std::variant<std::string>(bootModeStr));
1741cd9a4666SKonstantin Aladyshev }
1742944ffaf9SJohnathan Mantey 
1743cd9a4666SKonstantin Aladyshev /**
1744c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1745491d8ee7SSantosh Puranik  *
1746491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1747491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1748cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1749491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1750491d8ee7SSantosh Puranik  *
1751265c1602SJohnathan Mantey  * @return Integer error code.
1752491d8ee7SSantosh Puranik  */
1753c21865c4SKonstantin Aladyshev 
1754c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1755c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1756c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1757c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1758491d8ee7SSantosh Puranik {
1759491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1760491d8ee7SSantosh Puranik 
1761c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1762c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1763c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1764491d8ee7SSantosh Puranik }
1765491d8ee7SSantosh Puranik 
1766c6a620f2SGeorge Liu /**
176798e386ecSGunnar Mills  * @brief Sets AssetTag
176898e386ecSGunnar Mills  *
176998e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
177098e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
177198e386ecSGunnar Mills  *
177298e386ecSGunnar Mills  * @return None.
177398e386ecSGunnar Mills  */
17748d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
177598e386ecSGunnar Mills                         const std::string& assetTag)
177698e386ecSGunnar Mills {
177798e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
177898e386ecSGunnar Mills         [aResp, assetTag](
177998e386ecSGunnar Mills             const boost::system::error_code ec,
178098e386ecSGunnar Mills             const std::vector<std::pair<
178198e386ecSGunnar Mills                 std::string,
178298e386ecSGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
178398e386ecSGunnar Mills                 subtree) {
178498e386ecSGunnar Mills             if (ec)
178598e386ecSGunnar Mills             {
178698e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
178798e386ecSGunnar Mills                 messages::internalError(aResp->res);
178898e386ecSGunnar Mills                 return;
178998e386ecSGunnar Mills             }
179098e386ecSGunnar Mills             if (subtree.size() == 0)
179198e386ecSGunnar Mills             {
179298e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
179398e386ecSGunnar Mills                 messages::internalError(aResp->res);
179498e386ecSGunnar Mills                 return;
179598e386ecSGunnar Mills             }
179698e386ecSGunnar Mills             // Assume only 1 system D-Bus object
179798e386ecSGunnar Mills             // Throw an error if there is more than 1
179898e386ecSGunnar Mills             if (subtree.size() > 1)
179998e386ecSGunnar Mills             {
180098e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
180198e386ecSGunnar Mills                 messages::internalError(aResp->res);
180298e386ecSGunnar Mills                 return;
180398e386ecSGunnar Mills             }
180498e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
180598e386ecSGunnar Mills             {
180698e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
180798e386ecSGunnar Mills                 messages::internalError(aResp->res);
180898e386ecSGunnar Mills                 return;
180998e386ecSGunnar Mills             }
181098e386ecSGunnar Mills 
181198e386ecSGunnar Mills             const std::string& path = subtree[0].first;
181298e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
181398e386ecSGunnar Mills 
181498e386ecSGunnar Mills             if (service.empty())
181598e386ecSGunnar Mills             {
181698e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
181798e386ecSGunnar Mills                 messages::internalError(aResp->res);
181898e386ecSGunnar Mills                 return;
181998e386ecSGunnar Mills             }
182098e386ecSGunnar Mills 
182198e386ecSGunnar Mills             crow::connections::systemBus->async_method_call(
182298e386ecSGunnar Mills                 [aResp](const boost::system::error_code ec2) {
182398e386ecSGunnar Mills                     if (ec2)
182498e386ecSGunnar Mills                     {
182598e386ecSGunnar Mills                         BMCWEB_LOG_DEBUG
182698e386ecSGunnar Mills                             << "D-Bus response error on AssetTag Set " << ec2;
182798e386ecSGunnar Mills                         messages::internalError(aResp->res);
182898e386ecSGunnar Mills                         return;
182998e386ecSGunnar Mills                     }
183098e386ecSGunnar Mills                 },
183198e386ecSGunnar Mills                 service, path, "org.freedesktop.DBus.Properties", "Set",
183298e386ecSGunnar Mills                 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
183398e386ecSGunnar Mills                 std::variant<std::string>(assetTag));
183498e386ecSGunnar Mills         },
183598e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
183698e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
183798e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
183898e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
183998e386ecSGunnar Mills         std::array<const char*, 1>{
184098e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
184198e386ecSGunnar Mills }
184298e386ecSGunnar Mills 
184398e386ecSGunnar Mills /**
184469f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
184569f35306SGunnar Mills  *
184669f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
184769f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
184869f35306SGunnar Mills  *
184969f35306SGunnar Mills  * @return None.
185069f35306SGunnar Mills  */
18518d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1852f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
185369f35306SGunnar Mills {
185469f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
185569f35306SGunnar Mills 
185669f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
185769f35306SGunnar Mills     bool autoRebootEnabled;
185869f35306SGunnar Mills 
185969f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
186069f35306SGunnar Mills     {
186169f35306SGunnar Mills         autoRebootEnabled = false;
186269f35306SGunnar Mills     }
186369f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
186469f35306SGunnar Mills     {
186569f35306SGunnar Mills         autoRebootEnabled = true;
186669f35306SGunnar Mills     }
186769f35306SGunnar Mills     else
186869f35306SGunnar Mills     {
1869*0fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
187069f35306SGunnar Mills                          << automaticRetryConfig;
187169f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
187269f35306SGunnar Mills                                          "AutomaticRetryConfig");
187369f35306SGunnar Mills         return;
187469f35306SGunnar Mills     }
187569f35306SGunnar Mills 
187669f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
187769f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
187869f35306SGunnar Mills             if (ec)
187969f35306SGunnar Mills             {
188069f35306SGunnar Mills                 messages::internalError(aResp->res);
188169f35306SGunnar Mills                 return;
188269f35306SGunnar Mills             }
188369f35306SGunnar Mills         },
188469f35306SGunnar Mills         "xyz.openbmc_project.Settings",
188569f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
188669f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
188769f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
188869f35306SGunnar Mills         std::variant<bool>(autoRebootEnabled));
188969f35306SGunnar Mills }
189069f35306SGunnar Mills 
189169f35306SGunnar Mills /**
1892c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1893c6a620f2SGeorge Liu  *
1894c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1895c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1896c6a620f2SGeorge Liu  *
1897c6a620f2SGeorge Liu  * @return None.
1898c6a620f2SGeorge Liu  */
18998d1b46d7Szhanghch05 inline void
19008d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19014e69c904SGunnar Mills                           const std::string& policy)
1902c6a620f2SGeorge Liu {
1903c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1904c6a620f2SGeorge Liu 
1905c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
1906*0fda0f12SGeorge Liu         {"AlwaysOn",
1907*0fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
1908*0fda0f12SGeorge Liu         {"AlwaysOff",
1909*0fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
1910*0fda0f12SGeorge Liu         {"LastState",
1911*0fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1912c6a620f2SGeorge Liu 
1913c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1914c6a620f2SGeorge Liu 
19154e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1916c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1917c6a620f2SGeorge Liu     {
19184e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
19194e69c904SGunnar Mills                                          "PowerRestorePolicy");
1920c6a620f2SGeorge Liu         return;
1921c6a620f2SGeorge Liu     }
1922c6a620f2SGeorge Liu 
1923c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1924c6a620f2SGeorge Liu 
1925c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1926c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1927c6a620f2SGeorge Liu             if (ec)
1928c6a620f2SGeorge Liu             {
1929c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1930c6a620f2SGeorge Liu                 return;
1931c6a620f2SGeorge Liu             }
1932c6a620f2SGeorge Liu         },
1933c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1934c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1935c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1936c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1937c6a620f2SGeorge Liu         std::variant<std::string>(powerRestorPolicy));
1938c6a620f2SGeorge Liu }
1939c6a620f2SGeorge Liu 
1940a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1941a6349918SAppaRao Puli /**
1942a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1943a6349918SAppaRao Puli  *
1944a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1945a6349918SAppaRao Puli  *
1946a6349918SAppaRao Puli  * @return None.
1947a6349918SAppaRao Puli  */
19488d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1949a6349918SAppaRao Puli {
1950a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1951a6349918SAppaRao Puli     crow::connections::systemBus->async_method_call(
1952a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
19531214b7e7SGunnar Mills                 const std::vector<std::pair<std::string, VariantType>>&
19541214b7e7SGunnar Mills                     propertiesList) {
1955b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1956b99fb1a9SAppaRao Puli                 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
195750626f4fSJames Feist             aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
195850626f4fSJames Feist                 "#OemComputerSystem.OpenBmc";
195950626f4fSJames Feist             oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
196050626f4fSJames Feist 
1961a6349918SAppaRao Puli             if (ec)
1962a6349918SAppaRao Puli             {
1963a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1964b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1965b99fb1a9SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1966a6349918SAppaRao Puli                 return;
1967a6349918SAppaRao Puli             }
1968a6349918SAppaRao Puli 
1969a6349918SAppaRao Puli             const bool* provState = nullptr;
1970a6349918SAppaRao Puli             const bool* lockState = nullptr;
1971a6349918SAppaRao Puli             for (const std::pair<std::string, VariantType>& property :
1972a6349918SAppaRao Puli                  propertiesList)
1973a6349918SAppaRao Puli             {
1974a6349918SAppaRao Puli                 if (property.first == "UfmProvisioned")
1975a6349918SAppaRao Puli                 {
1976a6349918SAppaRao Puli                     provState = std::get_if<bool>(&property.second);
1977a6349918SAppaRao Puli                 }
1978a6349918SAppaRao Puli                 else if (property.first == "UfmLocked")
1979a6349918SAppaRao Puli                 {
1980a6349918SAppaRao Puli                     lockState = std::get_if<bool>(&property.second);
1981a6349918SAppaRao Puli                 }
1982a6349918SAppaRao Puli             }
1983a6349918SAppaRao Puli 
1984a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
1985a6349918SAppaRao Puli             {
1986a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1987a6349918SAppaRao Puli                 messages::internalError(aResp->res);
1988a6349918SAppaRao Puli                 return;
1989a6349918SAppaRao Puli             }
1990a6349918SAppaRao Puli 
1991a6349918SAppaRao Puli             if (*provState == true)
1992a6349918SAppaRao Puli             {
1993a6349918SAppaRao Puli                 if (*lockState == true)
1994a6349918SAppaRao Puli                 {
1995a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1996a6349918SAppaRao Puli                 }
1997a6349918SAppaRao Puli                 else
1998a6349918SAppaRao Puli                 {
1999a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2000a6349918SAppaRao Puli                 }
2001a6349918SAppaRao Puli             }
2002a6349918SAppaRao Puli             else
2003a6349918SAppaRao Puli             {
2004a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2005a6349918SAppaRao Puli             }
2006a6349918SAppaRao Puli         },
2007a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
2008a6349918SAppaRao Puli         "org.freedesktop.DBus.Properties", "GetAll",
2009a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Attributes");
2010a6349918SAppaRao Puli }
2011a6349918SAppaRao Puli #endif
2012a6349918SAppaRao Puli 
2013491d8ee7SSantosh Puranik /**
20143a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
20153a2d0424SChris Cain  *
20163a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20173a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
20183a2d0424SChris Cain  *
20193a2d0424SChris Cain  * @return None.
20203a2d0424SChris Cain  */
20213a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20223a2d0424SChris Cain                                const std::string& modeValue)
20233a2d0424SChris Cain {
20243a2d0424SChris Cain     std::string modeString;
20253a2d0424SChris Cain 
2026*0fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20273a2d0424SChris Cain     {
20283a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
20293a2d0424SChris Cain     }
2030*0fda0f12SGeorge Liu     else if (
2031*0fda0f12SGeorge Liu         modeValue ==
2032*0fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20333a2d0424SChris Cain     {
20343a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20353a2d0424SChris Cain     }
2036*0fda0f12SGeorge Liu     else if (modeValue ==
2037*0fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20383a2d0424SChris Cain     {
20393a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20403a2d0424SChris Cain     }
2041*0fda0f12SGeorge Liu     else if (modeValue ==
2042*0fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20433a2d0424SChris Cain     {
20443a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20453a2d0424SChris Cain     }
20463a2d0424SChris Cain     else
20473a2d0424SChris Cain     {
20483a2d0424SChris Cain         // Any other values would be invalid
20493a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20503a2d0424SChris Cain         messages::internalError(aResp->res);
20513a2d0424SChris Cain     }
20523a2d0424SChris Cain }
20533a2d0424SChris Cain 
20543a2d0424SChris Cain /**
20553a2d0424SChris Cain  * @brief Retrieves system power mode
20563a2d0424SChris Cain  *
20573a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20583a2d0424SChris Cain  *
20593a2d0424SChris Cain  * @return None.
20603a2d0424SChris Cain  */
20613a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
20623a2d0424SChris Cain {
20633a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
20643a2d0424SChris Cain 
20653a2d0424SChris Cain     // Get Power Mode object path:
20663a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
20673a2d0424SChris Cain         [aResp](
20683a2d0424SChris Cain             const boost::system::error_code ec,
20693a2d0424SChris Cain             const std::vector<std::pair<
20703a2d0424SChris Cain                 std::string,
20713a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
20723a2d0424SChris Cain                 subtree) {
20733a2d0424SChris Cain             if (ec)
20743a2d0424SChris Cain             {
20753a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20763a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
20773a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
20783a2d0424SChris Cain                 // error occurs
20793a2d0424SChris Cain                 return;
20803a2d0424SChris Cain             }
20813a2d0424SChris Cain             if (subtree.empty())
20823a2d0424SChris Cain             {
20833a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
20843a2d0424SChris Cain                 // if there is no instance found
20853a2d0424SChris Cain                 return;
20863a2d0424SChris Cain             }
20873a2d0424SChris Cain             if (subtree.size() > 1)
20883a2d0424SChris Cain             {
20893a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
20903a2d0424SChris Cain                 // error
20913a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20923a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
20933a2d0424SChris Cain                     << subtree.size();
20943a2d0424SChris Cain                 messages::internalError(aResp->res);
20953a2d0424SChris Cain                 return;
20963a2d0424SChris Cain             }
20973a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
20983a2d0424SChris Cain             {
20993a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21003a2d0424SChris Cain                 messages::internalError(aResp->res);
21013a2d0424SChris Cain                 return;
21023a2d0424SChris Cain             }
21033a2d0424SChris Cain             const std::string& path = subtree[0].first;
21043a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21053a2d0424SChris Cain             if (service.empty())
21063a2d0424SChris Cain             {
21073a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21083a2d0424SChris Cain                 messages::internalError(aResp->res);
21093a2d0424SChris Cain                 return;
21103a2d0424SChris Cain             }
21113a2d0424SChris Cain             // Valid Power Mode object found, now read the current value
21123a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
21133a2d0424SChris Cain                 [aResp](const boost::system::error_code ec,
21143a2d0424SChris Cain                         const std::variant<std::string>& pmode) {
21153a2d0424SChris Cain                     if (ec)
21163a2d0424SChris Cain                     {
21173a2d0424SChris Cain                         BMCWEB_LOG_DEBUG
21183a2d0424SChris Cain                             << "DBUS response error on PowerMode Get: " << ec;
21193a2d0424SChris Cain                         messages::internalError(aResp->res);
21203a2d0424SChris Cain                         return;
21213a2d0424SChris Cain                     }
21223a2d0424SChris Cain 
21233a2d0424SChris Cain                     const std::string* s = std::get_if<std::string>(&pmode);
21243a2d0424SChris Cain                     if (s == nullptr)
21253a2d0424SChris Cain                     {
21263a2d0424SChris Cain                         BMCWEB_LOG_DEBUG << "Unable to get PowerMode value";
21273a2d0424SChris Cain                         messages::internalError(aResp->res);
21283a2d0424SChris Cain                         return;
21293a2d0424SChris Cain                     }
21303a2d0424SChris Cain 
21313a2d0424SChris Cain                     aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] =
21323a2d0424SChris Cain                         {"Static", "MaximumPerformance", "PowerSaving"};
21333a2d0424SChris Cain 
21343a2d0424SChris Cain                     BMCWEB_LOG_DEBUG << "Current power mode: " << *s;
21353a2d0424SChris Cain                     translatePowerMode(aResp, *s);
21363a2d0424SChris Cain                 },
21373a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Get",
21383a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode");
21393a2d0424SChris Cain         },
21403a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
21413a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
21423a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
21433a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
21443a2d0424SChris Cain }
21453a2d0424SChris Cain 
21463a2d0424SChris Cain /**
21473a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21483a2d0424SChris Cain  * name associated with that string
21493a2d0424SChris Cain  *
21503a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21513a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21523a2d0424SChris Cain  *
21533a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21543a2d0424SChris Cain  */
21553a2d0424SChris Cain inline std::string
21563a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21573a2d0424SChris Cain                       const std::string& modeString)
21583a2d0424SChris Cain {
21593a2d0424SChris Cain     std::string mode;
21603a2d0424SChris Cain 
21613a2d0424SChris Cain     if (modeString == "Static")
21623a2d0424SChris Cain     {
21633a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21643a2d0424SChris Cain     }
21653a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21663a2d0424SChris Cain     {
2167*0fda0f12SGeorge Liu         mode =
2168*0fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21693a2d0424SChris Cain     }
21703a2d0424SChris Cain     else if (modeString == "PowerSaving")
21713a2d0424SChris Cain     {
21723a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21733a2d0424SChris Cain     }
21743a2d0424SChris Cain     else
21753a2d0424SChris Cain     {
21763a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
21773a2d0424SChris Cain     }
21783a2d0424SChris Cain     return mode;
21793a2d0424SChris Cain }
21803a2d0424SChris Cain 
21813a2d0424SChris Cain /**
21823a2d0424SChris Cain  * @brief Sets system power mode.
21833a2d0424SChris Cain  *
21843a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21853a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
21863a2d0424SChris Cain  *
21873a2d0424SChris Cain  * @return None.
21883a2d0424SChris Cain  */
21893a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21903a2d0424SChris Cain                          const std::string& pmode)
21913a2d0424SChris Cain {
21923a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
21933a2d0424SChris Cain 
21943a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
21953a2d0424SChris Cain     if (powerMode.empty())
21963a2d0424SChris Cain     {
21973a2d0424SChris Cain         return;
21983a2d0424SChris Cain     }
21993a2d0424SChris Cain 
22003a2d0424SChris Cain     // Get Power Mode object path:
22013a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
22023a2d0424SChris Cain         [aResp, powerMode](
22033a2d0424SChris Cain             const boost::system::error_code ec,
22043a2d0424SChris Cain             const std::vector<std::pair<
22053a2d0424SChris Cain                 std::string,
22063a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
22073a2d0424SChris Cain                 subtree) {
22083a2d0424SChris Cain             if (ec)
22093a2d0424SChris Cain             {
22103a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22113a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
22123a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22133a2d0424SChris Cain                 messages::internalError(aResp->res);
22143a2d0424SChris Cain                 return;
22153a2d0424SChris Cain             }
22163a2d0424SChris Cain             if (subtree.empty())
22173a2d0424SChris Cain             {
22183a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22193a2d0424SChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
22203a2d0424SChris Cain                                            "PowerMode");
22213a2d0424SChris Cain                 return;
22223a2d0424SChris Cain             }
22233a2d0424SChris Cain             if (subtree.size() > 1)
22243a2d0424SChris Cain             {
22253a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
22263a2d0424SChris Cain                 // error
22273a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22283a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
22293a2d0424SChris Cain                     << subtree.size();
22303a2d0424SChris Cain                 messages::internalError(aResp->res);
22313a2d0424SChris Cain                 return;
22323a2d0424SChris Cain             }
22333a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22343a2d0424SChris Cain             {
22353a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
22363a2d0424SChris Cain                 messages::internalError(aResp->res);
22373a2d0424SChris Cain                 return;
22383a2d0424SChris Cain             }
22393a2d0424SChris Cain             const std::string& path = subtree[0].first;
22403a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
22413a2d0424SChris Cain             if (service.empty())
22423a2d0424SChris Cain             {
22433a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
22443a2d0424SChris Cain                 messages::internalError(aResp->res);
22453a2d0424SChris Cain                 return;
22463a2d0424SChris Cain             }
22473a2d0424SChris Cain 
22483a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22493a2d0424SChris Cain                              << path;
22503a2d0424SChris Cain 
22513a2d0424SChris Cain             // Set the Power Mode property
22523a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
22533a2d0424SChris Cain                 [aResp](const boost::system::error_code ec) {
22543a2d0424SChris Cain                     if (ec)
22553a2d0424SChris Cain                     {
22563a2d0424SChris Cain                         messages::internalError(aResp->res);
22573a2d0424SChris Cain                         return;
22583a2d0424SChris Cain                     }
22593a2d0424SChris Cain                 },
22603a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
22613a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
22623a2d0424SChris Cain                 std::variant<std::string>(powerMode));
22633a2d0424SChris Cain         },
22643a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
22653a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
22663a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
22673a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
22683a2d0424SChris Cain }
22693a2d0424SChris Cain 
22703a2d0424SChris Cain /**
227151709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
227251709ffdSYong Li  *
227351709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
227451709ffdSYong Li  *
227551709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
227651709ffdSYong Li  * translation cannot be done, returns an empty string.
227751709ffdSYong Li  */
227823a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
227951709ffdSYong Li {
228051709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
228151709ffdSYong Li     {
228251709ffdSYong Li         return "None";
228351709ffdSYong Li     }
22843174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
228551709ffdSYong Li     {
228651709ffdSYong Li         return "ResetSystem";
228751709ffdSYong Li     }
22883174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
228951709ffdSYong Li     {
229051709ffdSYong Li         return "PowerDown";
229151709ffdSYong Li     }
22923174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
229351709ffdSYong Li     {
229451709ffdSYong Li         return "PowerCycle";
229551709ffdSYong Li     }
229651709ffdSYong Li 
229751709ffdSYong Li     return "";
229851709ffdSYong Li }
229951709ffdSYong Li 
230051709ffdSYong Li /**
2301c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2302c45f0082SYong Li  *
2303c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2304c45f0082SYong Li  *
2305c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2306c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2307c45f0082SYong Li  */
2308c45f0082SYong Li 
230923a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2310c45f0082SYong Li {
2311c45f0082SYong Li     if (rfAction == "None")
2312c45f0082SYong Li     {
2313c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2314c45f0082SYong Li     }
23153174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2316c45f0082SYong Li     {
2317c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2318c45f0082SYong Li     }
23193174e4dfSEd Tanous     if (rfAction == "PowerDown")
2320c45f0082SYong Li     {
2321c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2322c45f0082SYong Li     }
23233174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2324c45f0082SYong Li     {
2325c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2326c45f0082SYong Li     }
2327c45f0082SYong Li 
2328c45f0082SYong Li     return "";
2329c45f0082SYong Li }
2330c45f0082SYong Li 
2331c45f0082SYong Li /**
233251709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
233351709ffdSYong Li  *
233451709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
233551709ffdSYong Li  *
233651709ffdSYong Li  * @return None.
233751709ffdSYong Li  */
23388d1b46d7Szhanghch05 inline void
23398d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
234051709ffdSYong Li {
234151709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
234251709ffdSYong Li     crow::connections::systemBus->async_method_call(
234351709ffdSYong Li         [aResp](const boost::system::error_code ec,
234451709ffdSYong Li                 PropertiesType& properties) {
234551709ffdSYong Li             if (ec)
234651709ffdSYong Li             {
234751709ffdSYong Li                 // watchdog service is stopped
234851709ffdSYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
234951709ffdSYong Li                 return;
235051709ffdSYong Li             }
235151709ffdSYong Li 
235251709ffdSYong Li             BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
235351709ffdSYong Li 
235451709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
235551709ffdSYong Li                 aResp->res.jsonValue["HostWatchdogTimer"];
235651709ffdSYong Li 
235751709ffdSYong Li             // watchdog service is running/enabled
235851709ffdSYong Li             hostWatchdogTimer["Status"]["State"] = "Enabled";
235951709ffdSYong Li 
236051709ffdSYong Li             for (const auto& property : properties)
236151709ffdSYong Li             {
236251709ffdSYong Li                 BMCWEB_LOG_DEBUG << "prop=" << property.first;
236351709ffdSYong Li                 if (property.first == "Enabled")
236451709ffdSYong Li                 {
236551709ffdSYong Li                     const bool* state = std::get_if<bool>(&property.second);
236651709ffdSYong Li 
236751709ffdSYong Li                     if (!state)
236851709ffdSYong Li                     {
236951709ffdSYong Li                         messages::internalError(aResp->res);
2370601af5edSChicago Duan                         return;
237151709ffdSYong Li                     }
237251709ffdSYong Li 
237351709ffdSYong Li                     hostWatchdogTimer["FunctionEnabled"] = *state;
237451709ffdSYong Li                 }
237551709ffdSYong Li                 else if (property.first == "ExpireAction")
237651709ffdSYong Li                 {
237751709ffdSYong Li                     const std::string* s =
237851709ffdSYong Li                         std::get_if<std::string>(&property.second);
237951709ffdSYong Li                     if (!s)
238051709ffdSYong Li                     {
238151709ffdSYong Li                         messages::internalError(aResp->res);
2382601af5edSChicago Duan                         return;
238351709ffdSYong Li                     }
238451709ffdSYong Li 
238551709ffdSYong Li                     std::string action = dbusToRfWatchdogAction(*s);
238651709ffdSYong Li                     if (action.empty())
238751709ffdSYong Li                     {
238851709ffdSYong Li                         messages::internalError(aResp->res);
2389601af5edSChicago Duan                         return;
239051709ffdSYong Li                     }
239151709ffdSYong Li                     hostWatchdogTimer["TimeoutAction"] = action;
239251709ffdSYong Li                 }
239351709ffdSYong Li             }
239451709ffdSYong Li         },
239551709ffdSYong Li         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
239651709ffdSYong Li         "org.freedesktop.DBus.Properties", "GetAll",
239751709ffdSYong Li         "xyz.openbmc_project.State.Watchdog");
239851709ffdSYong Li }
239951709ffdSYong Li 
240051709ffdSYong Li /**
2401c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2402c45f0082SYong Li  *
2403c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2404c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2405c45f0082SYong Li  *                       RF request.
2406c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2407c45f0082SYong Li  *
2408c45f0082SYong Li  * @return None.
2409c45f0082SYong Li  */
24108d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2411c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2412c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2413c45f0082SYong Li {
2414c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2415c45f0082SYong Li 
2416c45f0082SYong Li     if (wdtTimeOutAction)
2417c45f0082SYong Li     {
2418c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2419c45f0082SYong Li         // check if TimeOut Action is Valid
2420c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2421c45f0082SYong Li         {
2422c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2423c45f0082SYong Li                              << *wdtTimeOutAction;
2424c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2425c45f0082SYong Li                                              "TimeoutAction");
2426c45f0082SYong Li             return;
2427c45f0082SYong Li         }
2428c45f0082SYong Li 
2429c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2430c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2431c45f0082SYong Li                 if (ec)
2432c45f0082SYong Li                 {
2433c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2434c45f0082SYong Li                     messages::internalError(aResp->res);
2435c45f0082SYong Li                     return;
2436c45f0082SYong Li                 }
2437c45f0082SYong Li             },
2438c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2439c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2440c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2441c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2442c45f0082SYong Li             std::variant<std::string>(wdtTimeOutActStr));
2443c45f0082SYong Li     }
2444c45f0082SYong Li 
2445c45f0082SYong Li     if (wdtEnable)
2446c45f0082SYong Li     {
2447c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2448c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2449c45f0082SYong Li                 if (ec)
2450c45f0082SYong Li                 {
2451c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2452c45f0082SYong Li                     messages::internalError(aResp->res);
2453c45f0082SYong Li                     return;
2454c45f0082SYong Li                 }
2455c45f0082SYong Li             },
2456c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2457c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2458c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2459c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2460c45f0082SYong Li             std::variant<bool>(*wdtEnable));
2461c45f0082SYong Li     }
2462c45f0082SYong Li }
2463c45f0082SYong Li 
246437bbf98cSChris Cain using ipsPropertiesType =
246537bbf98cSChris Cain     std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>;
246637bbf98cSChris Cain /**
246737bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
246837bbf98cSChris Cain  *
246937bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
247037bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
247137bbf98cSChris Cain  *
247237bbf98cSChris Cain  * @return true if successful
247337bbf98cSChris Cain  */
2474f6674220SEd Tanous inline bool parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
247537bbf98cSChris Cain                                ipsPropertiesType& properties)
247637bbf98cSChris Cain {
247737bbf98cSChris Cain     for (const auto& property : properties)
247837bbf98cSChris Cain     {
247937bbf98cSChris Cain         if (property.first == "Enabled")
248037bbf98cSChris Cain         {
248137bbf98cSChris Cain             const bool* state = std::get_if<bool>(&property.second);
248237bbf98cSChris Cain             if (!state)
248337bbf98cSChris Cain             {
248437bbf98cSChris Cain                 return false;
248537bbf98cSChris Cain             }
248637bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *state;
248737bbf98cSChris Cain         }
248837bbf98cSChris Cain         else if (property.first == "EnterUtilizationPercent")
248937bbf98cSChris Cain         {
249037bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
249137bbf98cSChris Cain             if (!util)
249237bbf98cSChris Cain             {
249337bbf98cSChris Cain                 return false;
249437bbf98cSChris Cain             }
249537bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
249637bbf98cSChris Cain         }
249737bbf98cSChris Cain         else if (property.first == "EnterDwellTime")
249837bbf98cSChris Cain         {
249937bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
250037bbf98cSChris Cain             const uint64_t* timeMilliseconds =
250137bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
250237bbf98cSChris Cain             if (!timeMilliseconds)
250337bbf98cSChris Cain             {
250437bbf98cSChris Cain                 return false;
250537bbf98cSChris Cain             }
250637bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
250737bbf98cSChris Cain                 *timeMilliseconds);
250837bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
250937bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
251037bbf98cSChris Cain                     .count();
251137bbf98cSChris Cain         }
251237bbf98cSChris Cain         else if (property.first == "ExitUtilizationPercent")
251337bbf98cSChris Cain         {
251437bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
251537bbf98cSChris Cain             if (!util)
251637bbf98cSChris Cain             {
251737bbf98cSChris Cain                 return false;
251837bbf98cSChris Cain             }
251937bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
252037bbf98cSChris Cain         }
252137bbf98cSChris Cain         else if (property.first == "ExitDwellTime")
252237bbf98cSChris Cain         {
252337bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
252437bbf98cSChris Cain             const uint64_t* timeMilliseconds =
252537bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
252637bbf98cSChris Cain             if (!timeMilliseconds)
252737bbf98cSChris Cain             {
252837bbf98cSChris Cain                 return false;
252937bbf98cSChris Cain             }
253037bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
253137bbf98cSChris Cain                 *timeMilliseconds);
253237bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
253337bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
253437bbf98cSChris Cain                     .count();
253537bbf98cSChris Cain         }
253637bbf98cSChris Cain         else
253737bbf98cSChris Cain         {
253837bbf98cSChris Cain             BMCWEB_LOG_WARNING << "Unexpected IdlePowerSaver property: "
253937bbf98cSChris Cain                                << property.first;
254037bbf98cSChris Cain         }
254137bbf98cSChris Cain     }
254237bbf98cSChris Cain 
254337bbf98cSChris Cain     return true;
254437bbf98cSChris Cain }
254537bbf98cSChris Cain 
254637bbf98cSChris Cain /**
254737bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
254837bbf98cSChris Cain  *
254937bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
255037bbf98cSChris Cain  *
255137bbf98cSChris Cain  * @return None.
255237bbf98cSChris Cain  */
255337bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
255437bbf98cSChris Cain {
255537bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
255637bbf98cSChris Cain 
255737bbf98cSChris Cain     // Get IdlePowerSaver object path:
255837bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
255937bbf98cSChris Cain         [aResp](
256037bbf98cSChris Cain             const boost::system::error_code ec,
256137bbf98cSChris Cain             const std::vector<std::pair<
256237bbf98cSChris Cain                 std::string,
256337bbf98cSChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
256437bbf98cSChris Cain                 subtree) {
256537bbf98cSChris Cain             if (ec)
256637bbf98cSChris Cain             {
256737bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
256837bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
256937bbf98cSChris Cain                     << ec;
257037bbf98cSChris Cain                 messages::internalError(aResp->res);
257137bbf98cSChris Cain                 return;
257237bbf98cSChris Cain             }
257337bbf98cSChris Cain             if (subtree.empty())
257437bbf98cSChris Cain             {
257537bbf98cSChris Cain                 // This is an optional interface so just return
257637bbf98cSChris Cain                 // if there is no instance found
257737bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "No instances found";
257837bbf98cSChris Cain                 return;
257937bbf98cSChris Cain             }
258037bbf98cSChris Cain             if (subtree.size() > 1)
258137bbf98cSChris Cain             {
258237bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
258337bbf98cSChris Cain                 // is an error
258437bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
258537bbf98cSChris Cain                                     "Power.IdlePowerSaver objects: "
258637bbf98cSChris Cain                                  << subtree.size();
258737bbf98cSChris Cain                 messages::internalError(aResp->res);
258837bbf98cSChris Cain                 return;
258937bbf98cSChris Cain             }
259037bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
259137bbf98cSChris Cain             {
259237bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
259337bbf98cSChris Cain                 messages::internalError(aResp->res);
259437bbf98cSChris Cain                 return;
259537bbf98cSChris Cain             }
259637bbf98cSChris Cain             const std::string& path = subtree[0].first;
259737bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
259837bbf98cSChris Cain             if (service.empty())
259937bbf98cSChris Cain             {
260037bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
260137bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
260237bbf98cSChris Cain                 messages::internalError(aResp->res);
260337bbf98cSChris Cain                 return;
260437bbf98cSChris Cain             }
260537bbf98cSChris Cain 
260637bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
260737bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
260837bbf98cSChris Cain                 [aResp](const boost::system::error_code ec,
260937bbf98cSChris Cain                         ipsPropertiesType& properties) {
261037bbf98cSChris Cain                     if (ec)
261137bbf98cSChris Cain                     {
261237bbf98cSChris Cain                         BMCWEB_LOG_ERROR
261337bbf98cSChris Cain                             << "DBUS response error on IdlePowerSaver GetAll: "
261437bbf98cSChris Cain                             << ec;
261537bbf98cSChris Cain                         messages::internalError(aResp->res);
261637bbf98cSChris Cain                         return;
261737bbf98cSChris Cain                     }
261837bbf98cSChris Cain 
261937bbf98cSChris Cain                     if (parseIpsProperties(aResp, properties) == false)
262037bbf98cSChris Cain                     {
262137bbf98cSChris Cain                         messages::internalError(aResp->res);
262237bbf98cSChris Cain                         return;
262337bbf98cSChris Cain                     }
262437bbf98cSChris Cain                 },
262537bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "GetAll",
262637bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver");
262737bbf98cSChris Cain         },
262837bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
262937bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
263037bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
263137bbf98cSChris Cain         std::array<const char*, 1>{
263237bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
263337bbf98cSChris Cain 
263437bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
263537bbf98cSChris Cain }
263637bbf98cSChris Cain 
263737bbf98cSChris Cain /**
263837bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
263937bbf98cSChris Cain  *
264037bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
264137bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
264237bbf98cSChris Cain  *                       RF request.
264337bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
264437bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
264537bbf98cSChris Cain  * before entering idle state.
264637bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
264737bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
264837bbf98cSChris Cain  * before exiting idle state
264937bbf98cSChris Cain  *
265037bbf98cSChris Cain  * @return None.
265137bbf98cSChris Cain  */
265237bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
265337bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
265437bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
265537bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
265637bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
265737bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
265837bbf98cSChris Cain {
265937bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
266037bbf98cSChris Cain 
266137bbf98cSChris Cain     // Get IdlePowerSaver object path:
266237bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
266337bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
266437bbf98cSChris Cain          ipsExitTime](
266537bbf98cSChris Cain             const boost::system::error_code ec,
266637bbf98cSChris Cain             const std::vector<std::pair<
266737bbf98cSChris Cain                 std::string,
266837bbf98cSChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
266937bbf98cSChris Cain                 subtree) {
267037bbf98cSChris Cain             if (ec)
267137bbf98cSChris Cain             {
267237bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
267337bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
267437bbf98cSChris Cain                     << ec;
267537bbf98cSChris Cain                 messages::internalError(aResp->res);
267637bbf98cSChris Cain                 return;
267737bbf98cSChris Cain             }
267837bbf98cSChris Cain             if (subtree.empty())
267937bbf98cSChris Cain             {
268037bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
268137bbf98cSChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
268237bbf98cSChris Cain                                            "IdlePowerSaver");
268337bbf98cSChris Cain                 return;
268437bbf98cSChris Cain             }
268537bbf98cSChris Cain             if (subtree.size() > 1)
268637bbf98cSChris Cain             {
268737bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
268837bbf98cSChris Cain                 // is an error
2689*0fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
2690*0fda0f12SGeorge Liu                     << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
269137bbf98cSChris Cain                     << subtree.size();
269237bbf98cSChris Cain                 messages::internalError(aResp->res);
269337bbf98cSChris Cain                 return;
269437bbf98cSChris Cain             }
269537bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
269637bbf98cSChris Cain             {
269737bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
269837bbf98cSChris Cain                 messages::internalError(aResp->res);
269937bbf98cSChris Cain                 return;
270037bbf98cSChris Cain             }
270137bbf98cSChris Cain             const std::string& path = subtree[0].first;
270237bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
270337bbf98cSChris Cain             if (service.empty())
270437bbf98cSChris Cain             {
270537bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
270637bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
270737bbf98cSChris Cain                 messages::internalError(aResp->res);
270837bbf98cSChris Cain                 return;
270937bbf98cSChris Cain             }
271037bbf98cSChris Cain 
271137bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
271237bbf98cSChris Cain             // need to be updated
271337bbf98cSChris Cain 
271437bbf98cSChris Cain             if (ipsEnable)
271537bbf98cSChris Cain             {
271637bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
271737bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
271837bbf98cSChris Cain                         if (ec)
271937bbf98cSChris Cain                         {
272037bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
272137bbf98cSChris Cain                             messages::internalError(aResp->res);
272237bbf98cSChris Cain                             return;
272337bbf98cSChris Cain                         }
272437bbf98cSChris Cain                     },
272537bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
272637bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
272737bbf98cSChris Cain                     "Enabled", std::variant<bool>(*ipsEnable));
272837bbf98cSChris Cain             }
272937bbf98cSChris Cain             if (ipsEnterUtil)
273037bbf98cSChris Cain             {
273137bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
273237bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
273337bbf98cSChris Cain                         if (ec)
273437bbf98cSChris Cain                         {
273537bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
273637bbf98cSChris Cain                             messages::internalError(aResp->res);
273737bbf98cSChris Cain                             return;
273837bbf98cSChris Cain                         }
273937bbf98cSChris Cain                     },
274037bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
274137bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
274237bbf98cSChris Cain                     "EnterUtilizationPercent",
274337bbf98cSChris Cain                     std::variant<uint8_t>(*ipsEnterUtil));
274437bbf98cSChris Cain             }
274537bbf98cSChris Cain             if (ipsEnterTime)
274637bbf98cSChris Cain             {
274737bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
274837bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
274937bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
275037bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
275137bbf98cSChris Cain                         if (ec)
275237bbf98cSChris Cain                         {
275337bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
275437bbf98cSChris Cain                             messages::internalError(aResp->res);
275537bbf98cSChris Cain                             return;
275637bbf98cSChris Cain                         }
275737bbf98cSChris Cain                     },
275837bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
275937bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
276037bbf98cSChris Cain                     "EnterDwellTime", std::variant<uint64_t>(timeMilliseconds));
276137bbf98cSChris Cain             }
276237bbf98cSChris Cain             if (ipsExitUtil)
276337bbf98cSChris Cain             {
276437bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
276537bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
276637bbf98cSChris Cain                         if (ec)
276737bbf98cSChris Cain                         {
276837bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
276937bbf98cSChris Cain                             messages::internalError(aResp->res);
277037bbf98cSChris Cain                             return;
277137bbf98cSChris Cain                         }
277237bbf98cSChris Cain                     },
277337bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
277437bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
277537bbf98cSChris Cain                     "ExitUtilizationPercent",
277637bbf98cSChris Cain                     std::variant<uint8_t>(*ipsExitUtil));
277737bbf98cSChris Cain             }
277837bbf98cSChris Cain             if (ipsExitTime)
277937bbf98cSChris Cain             {
278037bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
278137bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
278237bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
278337bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
278437bbf98cSChris Cain                         if (ec)
278537bbf98cSChris Cain                         {
278637bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
278737bbf98cSChris Cain                             messages::internalError(aResp->res);
278837bbf98cSChris Cain                             return;
278937bbf98cSChris Cain                         }
279037bbf98cSChris Cain                     },
279137bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
279237bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
279337bbf98cSChris Cain                     "ExitDwellTime", std::variant<uint64_t>(timeMilliseconds));
279437bbf98cSChris Cain             }
279537bbf98cSChris Cain         },
279637bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
279737bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
279837bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
279937bbf98cSChris Cain         std::array<const char*, 1>{
280037bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
280137bbf98cSChris Cain 
280237bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
280337bbf98cSChris Cain }
280437bbf98cSChris Cain 
2805c45f0082SYong Li /**
2806c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2807c5b2abe0SLewanczyk, Dawid  * Schema
2808c5b2abe0SLewanczyk, Dawid  */
28097e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
28101abe55efSEd Tanous {
28117e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2812ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
28137e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
28144f48d5f6SEd Tanous             [](const crow::Request& /*req*/,
28157e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28168d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
28170f74e643SEd Tanous                     "#ComputerSystemCollection.ComputerSystemCollection";
28188d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28198d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2820462023adSSunitha Harish 
2821462023adSSunitha Harish                 crow::connections::systemBus->async_method_call(
28224f48d5f6SEd Tanous                     [asyncResp](const boost::system::error_code ec,
2823cb13a392SEd Tanous                                 const std::variant<std::string>& /*hostName*/) {
28242c70f800SEd Tanous                         nlohmann::json& ifaceArray =
2825462023adSSunitha Harish                             asyncResp->res.jsonValue["Members"];
28262c70f800SEd Tanous                         ifaceArray = nlohmann::json::array();
28277e860f15SJohn Edward Broadbent                         auto& count =
28287e860f15SJohn Edward Broadbent                             asyncResp->res.jsonValue["Members@odata.count"];
28292c70f800SEd Tanous                         ifaceArray.push_back(
2830cb13a392SEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/system"}});
283194bda602STim Lee                         count = ifaceArray.size();
2832cb13a392SEd Tanous                         if (!ec)
2833462023adSSunitha Harish                         {
2834462023adSSunitha Harish                             BMCWEB_LOG_DEBUG << "Hypervisor is available";
28352c70f800SEd Tanous                             ifaceArray.push_back(
28367e860f15SJohn Edward Broadbent                                 {{"@odata.id",
28377e860f15SJohn Edward Broadbent                                   "/redfish/v1/Systems/hypervisor"}});
28382c70f800SEd Tanous                             count = ifaceArray.size();
2839cb13a392SEd Tanous                         }
2840462023adSSunitha Harish                     },
28418e651fbfSSunitha Harish                     "xyz.openbmc_project.Settings",
28428e651fbfSSunitha Harish                     "/xyz/openbmc_project/network/hypervisor",
2843462023adSSunitha Harish                     "org.freedesktop.DBus.Properties", "Get",
28447e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.Network.SystemConfiguration",
28457e860f15SJohn Edward Broadbent                     "HostName");
28467e860f15SJohn Edward Broadbent             });
2847c5b2abe0SLewanczyk, Dawid }
28487e860f15SJohn Edward Broadbent 
28497e860f15SJohn Edward Broadbent /**
28507e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28517e860f15SJohn Edward Broadbent  */
28524f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28537e860f15SJohn Edward Broadbent {
28547e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
28557e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
28567e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
28577e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
28587e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
28597e860f15SJohn Edward Broadbent 
28607e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28617e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
28627e860f15SJohn Edward Broadbent             if (ec)
28637e860f15SJohn Edward Broadbent             {
28647e860f15SJohn Edward Broadbent                 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
28657e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
28667e860f15SJohn Edward Broadbent                 return;
28677e860f15SJohn Edward Broadbent             }
28687e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
28697e860f15SJohn Edward Broadbent         },
28707e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28717e860f15SJohn Edward Broadbent }
2872c5b2abe0SLewanczyk, Dawid 
2873c5b2abe0SLewanczyk, Dawid /**
2874cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2875cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2876cc340dd9SEd Tanous  */
28777e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2878cc340dd9SEd Tanous {
2879cc340dd9SEd Tanous     /**
2880cc340dd9SEd Tanous      * Function handles POST method request.
2881cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2882cc340dd9SEd Tanous      */
28837e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
28847e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2885ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
28867e860f15SJohn Edward Broadbent         .methods(
28877e860f15SJohn Edward Broadbent             boost::beast::http::verb::
28887e860f15SJohn Edward Broadbent                 post)([](const crow::Request& req,
28897e860f15SJohn Edward Broadbent                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28909712f8acSEd Tanous             std::string resetType;
28917e860f15SJohn Edward Broadbent             if (!json_util::readJson(req, asyncResp->res, "ResetType",
28927e860f15SJohn Edward Broadbent                                      resetType))
2893cc340dd9SEd Tanous             {
2894cc340dd9SEd Tanous                 return;
2895cc340dd9SEd Tanous             }
2896cc340dd9SEd Tanous 
2897d22c8396SJason M. Bills             // Get the command and host vs. chassis
2898cc340dd9SEd Tanous             std::string command;
2899d22c8396SJason M. Bills             bool hostCommand;
2900d4d25793SEd Tanous             if ((resetType == "On") || (resetType == "ForceOn"))
2901cc340dd9SEd Tanous             {
2902cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.On";
2903d22c8396SJason M. Bills                 hostCommand = true;
2904d22c8396SJason M. Bills             }
2905d22c8396SJason M. Bills             else if (resetType == "ForceOff")
2906d22c8396SJason M. Bills             {
2907d22c8396SJason M. Bills                 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2908d22c8396SJason M. Bills                 hostCommand = false;
2909d22c8396SJason M. Bills             }
2910d22c8396SJason M. Bills             else if (resetType == "ForceRestart")
2911d22c8396SJason M. Bills             {
291286a0851aSJason M. Bills                 command =
291386a0851aSJason M. Bills                     "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
291486a0851aSJason M. Bills                 hostCommand = true;
2915cc340dd9SEd Tanous             }
29169712f8acSEd Tanous             else if (resetType == "GracefulShutdown")
2917cc340dd9SEd Tanous             {
2918cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.Off";
2919d22c8396SJason M. Bills                 hostCommand = true;
2920cc340dd9SEd Tanous             }
29219712f8acSEd Tanous             else if (resetType == "GracefulRestart")
2922cc340dd9SEd Tanous             {
2923*0fda0f12SGeorge Liu                 command =
2924*0fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2925d22c8396SJason M. Bills                 hostCommand = true;
2926d22c8396SJason M. Bills             }
2927d22c8396SJason M. Bills             else if (resetType == "PowerCycle")
2928d22c8396SJason M. Bills             {
292986a0851aSJason M. Bills                 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
293086a0851aSJason M. Bills                 hostCommand = true;
2931cc340dd9SEd Tanous             }
2932bfd5b826SLakshminarayana R. Kammath             else if (resetType == "Nmi")
2933bfd5b826SLakshminarayana R. Kammath             {
2934bfd5b826SLakshminarayana R. Kammath                 doNMI(asyncResp);
2935bfd5b826SLakshminarayana R. Kammath                 return;
2936bfd5b826SLakshminarayana R. Kammath             }
2937cc340dd9SEd Tanous             else
2938cc340dd9SEd Tanous             {
29398d1b46d7Szhanghch05                 messages::actionParameterUnknown(asyncResp->res, "Reset",
29408d1b46d7Szhanghch05                                                  resetType);
2941cc340dd9SEd Tanous                 return;
2942cc340dd9SEd Tanous             }
2943cc340dd9SEd Tanous 
2944d22c8396SJason M. Bills             if (hostCommand)
2945d22c8396SJason M. Bills             {
2946cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
2947d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2948cc340dd9SEd Tanous                         if (ec)
2949cc340dd9SEd Tanous                         {
2950cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
29517e860f15SJohn Edward Broadbent                             if (ec.value() ==
29527e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2953d22c8396SJason M. Bills                             {
2954d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2955d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2956d22c8396SJason M. Bills                             }
2957d22c8396SJason M. Bills                             else
2958d22c8396SJason M. Bills                             {
2959f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
2960d22c8396SJason M. Bills                             }
2961cc340dd9SEd Tanous                             return;
2962cc340dd9SEd Tanous                         }
2963f12894f8SJason M. Bills                         messages::success(asyncResp->res);
2964cc340dd9SEd Tanous                     },
2965cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
2966cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
2967cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
29689712f8acSEd Tanous                     "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2969abf2add6SEd Tanous                     std::variant<std::string>{command});
2970cc340dd9SEd Tanous             }
2971d22c8396SJason M. Bills             else
2972d22c8396SJason M. Bills             {
2973d22c8396SJason M. Bills                 crow::connections::systemBus->async_method_call(
2974d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2975d22c8396SJason M. Bills                         if (ec)
2976d22c8396SJason M. Bills                         {
2977d22c8396SJason M. Bills                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
29787e860f15SJohn Edward Broadbent                             if (ec.value() ==
29797e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2980d22c8396SJason M. Bills                             {
2981d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2982d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2983d22c8396SJason M. Bills                             }
2984d22c8396SJason M. Bills                             else
2985d22c8396SJason M. Bills                             {
2986d22c8396SJason M. Bills                                 messages::internalError(asyncResp->res);
2987d22c8396SJason M. Bills                             }
2988d22c8396SJason M. Bills                             return;
2989d22c8396SJason M. Bills                         }
2990d22c8396SJason M. Bills                         messages::success(asyncResp->res);
2991d22c8396SJason M. Bills                     },
2992d22c8396SJason M. Bills                     "xyz.openbmc_project.State.Chassis",
2993d22c8396SJason M. Bills                     "/xyz/openbmc_project/state/chassis0",
2994d22c8396SJason M. Bills                     "org.freedesktop.DBus.Properties", "Set",
29957e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.State.Chassis",
29967e860f15SJohn Edward Broadbent                     "RequestedPowerTransition",
2997d22c8396SJason M. Bills                     std::variant<std::string>{command});
2998d22c8396SJason M. Bills             }
29997e860f15SJohn Edward Broadbent         });
3000d22c8396SJason M. Bills }
3001cc340dd9SEd Tanous 
3002cc340dd9SEd Tanous /**
30036617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
3004c5b2abe0SLewanczyk, Dawid  */
30057e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
30061abe55efSEd Tanous {
3007c5b2abe0SLewanczyk, Dawid 
3008c5b2abe0SLewanczyk, Dawid     /**
3009c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
3010c5b2abe0SLewanczyk, Dawid      */
30117e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3012ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
30137e860f15SJohn Edward Broadbent         .methods(
30147e860f15SJohn Edward Broadbent             boost::beast::http::verb::
30157e860f15SJohn Edward Broadbent                 get)([](const crow::Request&,
30167e860f15SJohn Edward Broadbent                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
30178d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.type"] =
301837bbf98cSChris Cain                 "#ComputerSystem.v1_16_0.ComputerSystem";
30198d1b46d7Szhanghch05             asyncResp->res.jsonValue["Name"] = "system";
30208d1b46d7Szhanghch05             asyncResp->res.jsonValue["Id"] = "system";
30218d1b46d7Szhanghch05             asyncResp->res.jsonValue["SystemType"] = "Physical";
30228d1b46d7Szhanghch05             asyncResp->res.jsonValue["Description"] = "Computer System";
30238d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
30248d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
30258d1b46d7Szhanghch05                 "Disabled";
30268d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
30278d1b46d7Szhanghch05                 uint64_t(0);
30288d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
30298d1b46d7Szhanghch05                 "Disabled";
30307e860f15SJohn Edward Broadbent             asyncResp->res.jsonValue["@odata.id"] =
30317e860f15SJohn Edward Broadbent                 "/redfish/v1/Systems/system";
303204a258f4SEd Tanous 
30338d1b46d7Szhanghch05             asyncResp->res.jsonValue["Processors"] = {
3034029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
30358d1b46d7Szhanghch05             asyncResp->res.jsonValue["Memory"] = {
3036029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
30378d1b46d7Szhanghch05             asyncResp->res.jsonValue["Storage"] = {
3038a25aeccfSNikhil Potade                 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
3039029573d4SEd Tanous 
30408d1b46d7Szhanghch05             asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
3041cc340dd9SEd Tanous                 {"target",
3042029573d4SEd Tanous                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
30431cb1a9e6SAppaRao Puli                 {"@Redfish.ActionInfo",
30441cb1a9e6SAppaRao Puli                  "/redfish/v1/Systems/system/ResetActionInfo"}};
3045c5b2abe0SLewanczyk, Dawid 
30468d1b46d7Szhanghch05             asyncResp->res.jsonValue["LogServices"] = {
3047029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
3048c4bf6374SJason M. Bills 
30498d1b46d7Szhanghch05             asyncResp->res.jsonValue["Bios"] = {
3050d82a3acdSCarol Wang                 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
3051d82a3acdSCarol Wang 
30528d1b46d7Szhanghch05             asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
3053c5d03ff4SJennifer Lee                 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
3054c5d03ff4SJennifer Lee 
30558d1b46d7Szhanghch05             asyncResp->res.jsonValue["Status"] = {
3056c5d03ff4SJennifer Lee                 {"Health", "OK"},
3057c5d03ff4SJennifer Lee                 {"State", "Enabled"},
3058c5d03ff4SJennifer Lee             };
30590e8ac5e7SGunnar Mills 
30600e8ac5e7SGunnar Mills             // Fill in SerialConsole info
30610e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
30620e8ac5e7SGunnar Mills                 15;
30630e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = {
30640e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
30650e8ac5e7SGunnar Mills             };
30660e8ac5e7SGunnar Mills             // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
30670e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["SSH"] = {
30680e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
30690e8ac5e7SGunnar Mills                 {"Port", 2200},
30700e8ac5e7SGunnar Mills                 // https://github.com/openbmc/docs/blob/master/console.md
30710e8ac5e7SGunnar Mills                 {"HotKeySequenceDisplay", "Press ~. to exit console"},
30720e8ac5e7SGunnar Mills             };
30730e8ac5e7SGunnar Mills 
30740e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
30750e8ac5e7SGunnar Mills             // Fill in GraphicalConsole info
30760e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["GraphicalConsole"] = {
30770e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
30780e8ac5e7SGunnar Mills                 {"MaxConcurrentSessions", 4},
30790e8ac5e7SGunnar Mills                 {"ConnectTypesSupported", {"KVMIP"}},
30800e8ac5e7SGunnar Mills             };
30810e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
3082e284a7c1SJames Feist             constexpr const std::array<const char*, 4> inventoryForSystems = {
3083b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
30842ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
3085e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
3086e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
3087b49ac873SJames Feist 
3088b49ac873SJames Feist             auto health = std::make_shared<HealthPopulate>(asyncResp);
3089b49ac873SJames Feist             crow::connections::systemBus->async_method_call(
3090b49ac873SJames Feist                 [health](const boost::system::error_code ec,
3091b49ac873SJames Feist                          std::vector<std::string>& resp) {
3092b49ac873SJames Feist                     if (ec)
3093b49ac873SJames Feist                     {
3094b49ac873SJames Feist                         // no inventory
3095b49ac873SJames Feist                         return;
3096b49ac873SJames Feist                     }
3097b49ac873SJames Feist 
3098b49ac873SJames Feist                     health->inventory = std::move(resp);
3099b49ac873SJames Feist                 },
3100b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper",
3101b49ac873SJames Feist                 "/xyz/openbmc_project/object_mapper",
3102b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
3103b49ac873SJames Feist                 int32_t(0), inventoryForSystems);
3104b49ac873SJames Feist 
3105b49ac873SJames Feist             health->populate();
3106b49ac873SJames Feist 
31078d1b46d7Szhanghch05             getMainChassisId(
31088d1b46d7Szhanghch05                 asyncResp, [](const std::string& chassisId,
31098d1b46d7Szhanghch05                               const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3110c5d03ff4SJennifer Lee                     aRsp->res.jsonValue["Links"]["Chassis"] = {
3111c5d03ff4SJennifer Lee                         {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
3112c5d03ff4SJennifer Lee                 });
3113a3002228SAppaRao Puli 
31149f8bfa7cSGunnar Mills             getLocationIndicatorActive(asyncResp);
31159f8bfa7cSGunnar Mills             // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3116a3002228SAppaRao Puli             getIndicatorLedState(asyncResp);
31175bc2dc8eSJames Feist             getComputerSystem(asyncResp, health);
31186c34de48SEd Tanous             getHostState(asyncResp);
3119491d8ee7SSantosh Puranik             getBootProperties(asyncResp);
3120978b8803SAndrew Geissler             getBootProgress(asyncResp);
3121adbe192aSJason M. Bills             getPCIeDeviceList(asyncResp, "PCIeDevices");
312251709ffdSYong Li             getHostWatchdogTimer(asyncResp);
3123c6a620f2SGeorge Liu             getPowerRestorePolicy(asyncResp);
31246bd5a8d2SGunnar Mills             getAutomaticRetry(asyncResp);
3125c0557e1aSGunnar Mills             getLastResetTime(asyncResp);
3126a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3127a6349918SAppaRao Puli             getProvisioningStatus(asyncResp);
3128a6349918SAppaRao Puli #endif
31291981771bSAli Ahmed             getTrustedModuleRequiredToBoot(asyncResp);
31303a2d0424SChris Cain             getPowerMode(asyncResp);
313137bbf98cSChris Cain             getIdlePowerSaver(asyncResp);
31327e860f15SJohn Edward Broadbent         });
31337e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3134ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
31357e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
31367e860f15SJohn Edward Broadbent             [](const crow::Request& req,
31377e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
31389f8bfa7cSGunnar Mills                 std::optional<bool> locationIndicatorActive;
3139cde19e5fSSantosh Puranik                 std::optional<std::string> indicatorLed;
3140491d8ee7SSantosh Puranik                 std::optional<nlohmann::json> bootProps;
3141c45f0082SYong Li                 std::optional<nlohmann::json> wdtTimerProps;
314298e386ecSGunnar Mills                 std::optional<std::string> assetTag;
3143c6a620f2SGeorge Liu                 std::optional<std::string> powerRestorePolicy;
31443a2d0424SChris Cain                 std::optional<std::string> powerMode;
314537bbf98cSChris Cain                 std::optional<nlohmann::json> ipsProps;
31469f8bfa7cSGunnar Mills                 if (!json_util::readJson(
31478d1b46d7Szhanghch05                         req, asyncResp->res, "IndicatorLED", indicatorLed,
31487e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
31497e860f15SJohn Edward Broadbent                         "Boot", bootProps, "WatchdogTimer", wdtTimerProps,
31507e860f15SJohn Edward Broadbent                         "PowerRestorePolicy", powerRestorePolicy, "AssetTag",
315137bbf98cSChris Cain                         assetTag, "PowerMode", powerMode, "IdlePowerSaver",
315237bbf98cSChris Cain                         ipsProps))
31536617338dSEd Tanous                 {
31546617338dSEd Tanous                     return;
31556617338dSEd Tanous                 }
3156491d8ee7SSantosh Puranik 
31578d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
3158c45f0082SYong Li 
315998e386ecSGunnar Mills                 if (assetTag)
316098e386ecSGunnar Mills                 {
316198e386ecSGunnar Mills                     setAssetTag(asyncResp, *assetTag);
316298e386ecSGunnar Mills                 }
316398e386ecSGunnar Mills 
3164c45f0082SYong Li                 if (wdtTimerProps)
3165c45f0082SYong Li                 {
3166c45f0082SYong Li                     std::optional<bool> wdtEnable;
3167c45f0082SYong Li                     std::optional<std::string> wdtTimeOutAction;
3168c45f0082SYong Li 
3169c45f0082SYong Li                     if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
3170c45f0082SYong Li                                              "FunctionEnabled", wdtEnable,
3171c45f0082SYong Li                                              "TimeoutAction", wdtTimeOutAction))
3172c45f0082SYong Li                     {
3173c45f0082SYong Li                         return;
3174c45f0082SYong Li                     }
3175f23b7296SEd Tanous                     setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3176c45f0082SYong Li                 }
3177c45f0082SYong Li 
3178491d8ee7SSantosh Puranik                 if (bootProps)
3179491d8ee7SSantosh Puranik                 {
3180491d8ee7SSantosh Puranik                     std::optional<std::string> bootSource;
3181cd9a4666SKonstantin Aladyshev                     std::optional<std::string> bootType;
3182491d8ee7SSantosh Puranik                     std::optional<std::string> bootEnable;
318369f35306SGunnar Mills                     std::optional<std::string> automaticRetryConfig;
3184ac7e1e0bSAli Ahmed                     std::optional<bool> trustedModuleRequiredToBoot;
3185491d8ee7SSantosh Puranik 
318669f35306SGunnar Mills                     if (!json_util::readJson(
31877e860f15SJohn Edward Broadbent                             *bootProps, asyncResp->res,
31887e860f15SJohn Edward Broadbent                             "BootSourceOverrideTarget", bootSource,
3189cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode", bootType,
31907e860f15SJohn Edward Broadbent                             "BootSourceOverrideEnabled", bootEnable,
3191ac7e1e0bSAli Ahmed                             "AutomaticRetryConfig", automaticRetryConfig,
3192ac7e1e0bSAli Ahmed                             "TrustedModuleRequiredToBoot",
3193ac7e1e0bSAli Ahmed                             trustedModuleRequiredToBoot))
3194491d8ee7SSantosh Puranik                     {
3195491d8ee7SSantosh Puranik                         return;
3196491d8ee7SSantosh Puranik                     }
3197c21865c4SKonstantin Aladyshev 
3198cd9a4666SKonstantin Aladyshev                     if (bootSource || bootType || bootEnable)
319969f35306SGunnar Mills                     {
3200c21865c4SKonstantin Aladyshev                         setBootProperties(asyncResp, bootSource, bootType,
3201c21865c4SKonstantin Aladyshev                                           bootEnable);
3202491d8ee7SSantosh Puranik                     }
320369f35306SGunnar Mills                     if (automaticRetryConfig)
320469f35306SGunnar Mills                     {
3205f23b7296SEd Tanous                         setAutomaticRetry(asyncResp, *automaticRetryConfig);
320669f35306SGunnar Mills                     }
3207ac7e1e0bSAli Ahmed 
3208ac7e1e0bSAli Ahmed                     if (trustedModuleRequiredToBoot)
3209ac7e1e0bSAli Ahmed                     {
3210ac7e1e0bSAli Ahmed                         setTrustedModuleRequiredToBoot(
3211ac7e1e0bSAli Ahmed                             asyncResp, *trustedModuleRequiredToBoot);
3212ac7e1e0bSAli Ahmed                     }
321369f35306SGunnar Mills                 }
3214265c1602SJohnathan Mantey 
32159f8bfa7cSGunnar Mills                 if (locationIndicatorActive)
32169f8bfa7cSGunnar Mills                 {
32177e860f15SJohn Edward Broadbent                     setLocationIndicatorActive(asyncResp,
32187e860f15SJohn Edward Broadbent                                                *locationIndicatorActive);
32199f8bfa7cSGunnar Mills                 }
32209f8bfa7cSGunnar Mills 
32217e860f15SJohn Edward Broadbent                 // TODO (Gunnar): Remove IndicatorLED after enough time has
32227e860f15SJohn Edward Broadbent                 // passed
32239712f8acSEd Tanous                 if (indicatorLed)
32246617338dSEd Tanous                 {
3225f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
32267e860f15SJohn Edward Broadbent                     asyncResp->res.addHeader(
32277e860f15SJohn Edward Broadbent                         boost::beast::http::field::warning,
3228d6aa0093SGunnar Mills                         "299 - \"IndicatorLED is deprecated. Use "
3229d6aa0093SGunnar Mills                         "LocationIndicatorActive instead.\"");
32306617338dSEd Tanous                 }
3231c6a620f2SGeorge Liu 
3232c6a620f2SGeorge Liu                 if (powerRestorePolicy)
3233c6a620f2SGeorge Liu                 {
32344e69c904SGunnar Mills                     setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3235c6a620f2SGeorge Liu                 }
32363a2d0424SChris Cain 
32373a2d0424SChris Cain                 if (powerMode)
32383a2d0424SChris Cain                 {
32393a2d0424SChris Cain                     setPowerMode(asyncResp, *powerMode);
32403a2d0424SChris Cain                 }
324137bbf98cSChris Cain 
324237bbf98cSChris Cain                 if (ipsProps)
324337bbf98cSChris Cain                 {
324437bbf98cSChris Cain                     std::optional<bool> ipsEnable;
324537bbf98cSChris Cain                     std::optional<uint8_t> ipsEnterUtil;
324637bbf98cSChris Cain                     std::optional<uint64_t> ipsEnterTime;
324737bbf98cSChris Cain                     std::optional<uint8_t> ipsExitUtil;
324837bbf98cSChris Cain                     std::optional<uint64_t> ipsExitTime;
324937bbf98cSChris Cain 
325037bbf98cSChris Cain                     if (!json_util::readJson(
325137bbf98cSChris Cain                             *ipsProps, asyncResp->res, "Enabled", ipsEnable,
325237bbf98cSChris Cain                             "EnterUtilizationPercent", ipsEnterUtil,
325337bbf98cSChris Cain                             "EnterDwellTimeSeconds", ipsEnterTime,
325437bbf98cSChris Cain                             "ExitUtilizationPercent", ipsExitUtil,
325537bbf98cSChris Cain                             "ExitDwellTimeSeconds", ipsExitTime))
325637bbf98cSChris Cain                     {
325737bbf98cSChris Cain                         return;
325837bbf98cSChris Cain                     }
325937bbf98cSChris Cain                     setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil,
326037bbf98cSChris Cain                                       ipsEnterTime, ipsExitUtil, ipsExitTime);
326137bbf98cSChris Cain                 }
32627e860f15SJohn Edward Broadbent             });
3263c5b2abe0SLewanczyk, Dawid }
32641cb1a9e6SAppaRao Puli 
32651cb1a9e6SAppaRao Puli /**
32661cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
32671cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
32681cb1a9e6SAppaRao Puli  */
32697e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
32701cb1a9e6SAppaRao Puli {
32711cb1a9e6SAppaRao Puli 
32721cb1a9e6SAppaRao Puli     /**
32731cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
32741cb1a9e6SAppaRao Puli      */
32757e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3276ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
32777e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
32787e860f15SJohn Edward Broadbent             [](const crow::Request&,
32797e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
32808d1b46d7Szhanghch05                 asyncResp->res.jsonValue = {
32811cb1a9e6SAppaRao Puli                     {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
32821cb1a9e6SAppaRao Puli                     {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
32831cb1a9e6SAppaRao Puli                     {"Name", "Reset Action Info"},
32841cb1a9e6SAppaRao Puli                     {"Id", "ResetActionInfo"},
32851cb1a9e6SAppaRao Puli                     {"Parameters",
32861cb1a9e6SAppaRao Puli                      {{{"Name", "ResetType"},
32871cb1a9e6SAppaRao Puli                        {"Required", true},
32881cb1a9e6SAppaRao Puli                        {"DataType", "String"},
32891cb1a9e6SAppaRao Puli                        {"AllowableValues",
32907e860f15SJohn Edward Broadbent                         {"On", "ForceOff", "ForceOn", "ForceRestart",
32917e860f15SJohn Edward Broadbent                          "GracefulRestart", "GracefulShutdown", "PowerCycle",
32927e860f15SJohn Edward Broadbent                          "Nmi"}}}}}};
32937e860f15SJohn Edward Broadbent             });
32941cb1a9e6SAppaRao Puli }
3295c5b2abe0SLewanczyk, Dawid } // namespace redfish
3296