xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 4ed47cb82da65cf8c84bb0be8ff98c6a208a550d)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
181e1e598dSJonathan Doman #include "dbus_singleton.hpp"
19b49ac873SJames Feist #include "health.hpp"
201c8fba97SJames Feist #include "led.hpp"
21f5c9f8bdSJason M. Bills #include "pcie.hpp"
22c5d03ff4SJennifer Lee #include "redfish_util.hpp"
23c5d03ff4SJennifer Lee 
247e860f15SJohn Edward Broadbent #include <app.hpp>
259712f8acSEd Tanous #include <boost/container/flat_map.hpp>
26168e20c1SEd Tanous #include <dbus_utility.hpp>
27ed398213SEd Tanous #include <registries/privilege_registry.hpp>
281e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
29cb7e1e7bSAndrew Geissler #include <utils/fw_utils.hpp>
30c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
311214b7e7SGunnar Mills 
32abf2add6SEd Tanous #include <variant>
33c5b2abe0SLewanczyk, Dawid 
341abe55efSEd Tanous namespace redfish
351abe55efSEd Tanous {
36c5b2abe0SLewanczyk, Dawid 
379d3ae10eSAlpana Kumari /**
389d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
399d3ae10eSAlpana Kumari  *
409d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
419d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
429d3ae10eSAlpana Kumari  *
439d3ae10eSAlpana Kumari  * @return None.
449d3ae10eSAlpana Kumari  */
458d1b46d7Szhanghch05 inline void
468d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
471e1e598dSJonathan Doman                          bool isDimmFunctional)
489d3ae10eSAlpana Kumari {
491e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
509d3ae10eSAlpana Kumari 
519d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
529d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
539d3ae10eSAlpana Kumari     // ENABLED.
549d3ae10eSAlpana Kumari     nlohmann::json& prevMemSummary =
559d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
569d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
579d3ae10eSAlpana Kumari     {
58e05aec50SEd Tanous         if (isDimmFunctional)
599d3ae10eSAlpana Kumari         {
609d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
619d3ae10eSAlpana Kumari                 "Enabled";
629d3ae10eSAlpana Kumari         }
639d3ae10eSAlpana Kumari     }
649d3ae10eSAlpana Kumari }
659d3ae10eSAlpana Kumari 
6657e8c9beSAlpana Kumari /*
6757e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
6857e8c9beSAlpana Kumari  *
6957e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
7057e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
7157e8c9beSAlpana Kumari  *
7257e8c9beSAlpana Kumari  * @return None.
7357e8c9beSAlpana Kumari  */
741e1e598dSJonathan Doman inline void
751e1e598dSJonathan Doman     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
761e1e598dSJonathan Doman                            bool isCpuPresent)
7757e8c9beSAlpana Kumari {
781e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
7957e8c9beSAlpana Kumari 
8055f79e6fSEd Tanous     if (isCpuPresent)
8157e8c9beSAlpana Kumari     {
82b4b9595aSJames Feist         nlohmann::json& procCount =
83b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
8455f79e6fSEd Tanous         auto* procCountPtr =
85b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
86b4b9595aSJames Feist         if (procCountPtr != nullptr)
87b4b9595aSJames Feist         {
88b4b9595aSJames Feist             // shouldn't be possible to be nullptr
89b4b9595aSJames Feist             *procCountPtr += 1;
9057e8c9beSAlpana Kumari         }
91b4b9595aSJames Feist     }
9257e8c9beSAlpana Kumari }
9357e8c9beSAlpana Kumari 
9457e8c9beSAlpana Kumari /*
9557e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9657e8c9beSAlpana Kumari  *        CPU Functional State
9757e8c9beSAlpana Kumari  *
9857e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
9957e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
10057e8c9beSAlpana Kumari  *
10157e8c9beSAlpana Kumari  * @return None.
10257e8c9beSAlpana Kumari  */
1031e1e598dSJonathan Doman inline void
1041e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1051e1e598dSJonathan Doman                              bool isCpuFunctional)
10657e8c9beSAlpana Kumari {
1071e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
10857e8c9beSAlpana Kumari 
10957e8c9beSAlpana Kumari     nlohmann::json& prevProcState =
11057e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
11157e8c9beSAlpana Kumari 
11257e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
11357e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
11457e8c9beSAlpana Kumari     // Functional.
11557e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11657e8c9beSAlpana Kumari     {
117e05aec50SEd Tanous         if (isCpuFunctional)
11857e8c9beSAlpana Kumari         {
11957e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
12057e8c9beSAlpana Kumari                 "Enabled";
12157e8c9beSAlpana Kumari         }
12257e8c9beSAlpana Kumari     }
12357e8c9beSAlpana Kumari }
12457e8c9beSAlpana Kumari 
12503fbed92SAli Ahmed inline void getProcessorProperties(
12603fbed92SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
12703fbed92SAli Ahmed     const std::string& path,
128168e20c1SEd Tanous     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
12903fbed92SAli Ahmed         properties)
13003fbed92SAli Ahmed {
13103fbed92SAli Ahmed 
13203fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
13303fbed92SAli Ahmed 
1341e1e598dSJonathan Doman     auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
1351e1e598dSJonathan Doman                                        const bool cpuPresenceCheck) {
13603fbed92SAli Ahmed         if (ec3)
13703fbed92SAli Ahmed         {
13803fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
13903fbed92SAli Ahmed             return;
14003fbed92SAli Ahmed         }
14103fbed92SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
14203fbed92SAli Ahmed     };
14303fbed92SAli Ahmed 
1441e1e598dSJonathan Doman     auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
1451e1e598dSJonathan Doman                                          const bool cpuFunctionalCheck) {
14603fbed92SAli Ahmed         if (ec3)
14703fbed92SAli Ahmed         {
14803fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
14903fbed92SAli Ahmed             return;
15003fbed92SAli Ahmed         }
15103fbed92SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
15203fbed92SAli Ahmed     };
15303fbed92SAli Ahmed 
15403fbed92SAli Ahmed     // Get the Presence of CPU
1551e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
1561e1e598dSJonathan Doman         *crow::connections::systemBus, service, path,
1571e1e598dSJonathan Doman         "xyz.openbmc_project.Inventory.Item", "Present",
1581e1e598dSJonathan Doman         std::move(getCpuPresenceState));
15903fbed92SAli Ahmed 
16003fbed92SAli Ahmed     // Get the Functional State
1611e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
1621e1e598dSJonathan Doman         *crow::connections::systemBus, service, path,
1631e1e598dSJonathan Doman         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
1641e1e598dSJonathan Doman         std::move(getCpuFunctionalState));
16503fbed92SAli Ahmed 
16603fbed92SAli Ahmed     for (const auto& property : properties)
16703fbed92SAli Ahmed     {
16803fbed92SAli Ahmed 
16903fbed92SAli Ahmed         // TODO: Get Model
17003fbed92SAli Ahmed 
17103fbed92SAli Ahmed         // Get CoreCount
17203fbed92SAli Ahmed         if (property.first == "CoreCount")
17303fbed92SAli Ahmed         {
17403fbed92SAli Ahmed 
17503fbed92SAli Ahmed             // Get CPU CoreCount and add it to the total
17603fbed92SAli Ahmed             const uint16_t* coreCountVal =
17703fbed92SAli Ahmed                 std::get_if<uint16_t>(&property.second);
17803fbed92SAli Ahmed 
179e662eae8SEd Tanous             if (coreCountVal == nullptr)
18003fbed92SAli Ahmed             {
18103fbed92SAli Ahmed                 messages::internalError(aResp->res);
18203fbed92SAli Ahmed                 return;
18303fbed92SAli Ahmed             }
18403fbed92SAli Ahmed 
18503fbed92SAli Ahmed             nlohmann::json& coreCount =
18603fbed92SAli Ahmed                 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
18703fbed92SAli Ahmed             uint64_t* coreCountPtr = coreCount.get_ptr<uint64_t*>();
18803fbed92SAli Ahmed 
18903fbed92SAli Ahmed             if (coreCountPtr == nullptr)
19003fbed92SAli Ahmed             {
19103fbed92SAli Ahmed                 coreCount = 0;
19203fbed92SAli Ahmed             }
19303fbed92SAli Ahmed             else
19403fbed92SAli Ahmed             {
19503fbed92SAli Ahmed                 *coreCountPtr += *coreCountVal;
19603fbed92SAli Ahmed             }
19703fbed92SAli Ahmed         }
19803fbed92SAli Ahmed     }
19903fbed92SAli Ahmed }
20003fbed92SAli Ahmed 
20103fbed92SAli Ahmed /*
20203fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
20303fbed92SAli Ahmed  *
20403fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
20503fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
20603fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
20703fbed92SAli Ahmed  *
20803fbed92SAli Ahmed  * @return None.
20903fbed92SAli Ahmed  */
21003fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21103fbed92SAli Ahmed                                 const std::string& service,
21203fbed92SAli Ahmed                                 const std::string& path)
21303fbed92SAli Ahmed {
21403fbed92SAli Ahmed 
21503fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
21603fbed92SAli Ahmed         [aResp, service,
21703fbed92SAli Ahmed          path](const boost::system::error_code ec2,
21803fbed92SAli Ahmed                const std::vector<std::pair<
219168e20c1SEd Tanous                    std::string, dbus::utility::DbusVariantType>>& properties) {
22003fbed92SAli Ahmed             if (ec2)
22103fbed92SAli Ahmed             {
22203fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
22303fbed92SAli Ahmed                 messages::internalError(aResp->res);
22403fbed92SAli Ahmed                 return;
22503fbed92SAli Ahmed             }
22603fbed92SAli Ahmed             getProcessorProperties(aResp, service, path, properties);
22703fbed92SAli Ahmed         },
22803fbed92SAli Ahmed         service, path, "org.freedesktop.DBus.Properties", "GetAll",
22903fbed92SAli Ahmed         "xyz.openbmc_project.Inventory.Item.Cpu");
23003fbed92SAli Ahmed }
23103fbed92SAli Ahmed 
23257e8c9beSAlpana Kumari /*
233c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
234c5b2abe0SLewanczyk, Dawid  *
235c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2368f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
237c5b2abe0SLewanczyk, Dawid  *
238c5b2abe0SLewanczyk, Dawid  * @return None.
239c5b2abe0SLewanczyk, Dawid  */
240b5a76932SEd Tanous inline void
2418d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
242b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2431abe55efSEd Tanous {
24455c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
2459d3ae10eSAlpana Kumari 
24655c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
2475bc2dc8eSJames Feist         [aResp, systemHealth](
248c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
249c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
2506c34de48SEd Tanous                 std::string,
2511214b7e7SGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
2521214b7e7SGunnar Mills                 subtree) {
2531abe55efSEd Tanous             if (ec)
2541abe55efSEd Tanous             {
25555c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
256f12894f8SJason M. Bills                 messages::internalError(aResp->res);
257c5b2abe0SLewanczyk, Dawid                 return;
258c5b2abe0SLewanczyk, Dawid             }
259c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
2606c34de48SEd Tanous             for (const std::pair<std::string,
2616c34de48SEd Tanous                                  std::vector<std::pair<
2621214b7e7SGunnar Mills                                      std::string, std::vector<std::string>>>>&
2631214b7e7SGunnar Mills                      object : subtree)
2641abe55efSEd Tanous             {
265c5b2abe0SLewanczyk, Dawid                 const std::string& path = object.first;
26655c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
2671abe55efSEd Tanous                 const std::vector<
2681214b7e7SGunnar Mills                     std::pair<std::string, std::vector<std::string>>>&
2691214b7e7SGunnar Mills                     connectionNames = object.second;
27026f6976fSEd Tanous                 if (connectionNames.empty())
2711abe55efSEd Tanous                 {
272c5b2abe0SLewanczyk, Dawid                     continue;
273c5b2abe0SLewanczyk, Dawid                 }
274029573d4SEd Tanous 
2755bc2dc8eSJames Feist                 auto memoryHealth = std::make_shared<HealthPopulate>(
2765bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
2775bc2dc8eSJames Feist 
2785bc2dc8eSJames Feist                 auto cpuHealth = std::make_shared<HealthPopulate>(
2795bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
2805bc2dc8eSJames Feist 
2815bc2dc8eSJames Feist                 systemHealth->children.emplace_back(memoryHealth);
2825bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
2835bc2dc8eSJames Feist 
2846c34de48SEd Tanous                 // This is not system, so check if it's cpu, dimm, UUID or
2856c34de48SEd Tanous                 // BiosVer
28604a258f4SEd Tanous                 for (const auto& connection : connectionNames)
2871abe55efSEd Tanous                 {
28804a258f4SEd Tanous                     for (const auto& interfaceName : connection.second)
2891abe55efSEd Tanous                     {
29004a258f4SEd Tanous                         if (interfaceName ==
29104a258f4SEd Tanous                             "xyz.openbmc_project.Inventory.Item.Dimm")
2921abe55efSEd Tanous                         {
2931abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
29404a258f4SEd Tanous                                 << "Found Dimm, now get its properties.";
2959d3ae10eSAlpana Kumari 
29655c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
2979d3ae10eSAlpana Kumari                                 [aResp, service{connection.first},
298f23b7296SEd Tanous                                  path](const boost::system::error_code ec2,
299168e20c1SEd Tanous                                        const std::vector<std::pair<
300168e20c1SEd Tanous                                            std::string,
301168e20c1SEd Tanous                                            dbus::utility::DbusVariantType>>&
3021214b7e7SGunnar Mills                                            properties) {
303cb13a392SEd Tanous                                     if (ec2)
3041abe55efSEd Tanous                                     {
3051abe55efSEd Tanous                                         BMCWEB_LOG_ERROR
306cb13a392SEd Tanous                                             << "DBUS response error " << ec2;
307f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
308c5b2abe0SLewanczyk, Dawid                                         return;
309c5b2abe0SLewanczyk, Dawid                                     }
3106c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
3116c34de48SEd Tanous                                                      << properties.size()
312c5b2abe0SLewanczyk, Dawid                                                      << " Dimm properties.";
3139d3ae10eSAlpana Kumari 
31426f6976fSEd Tanous                                     if (!properties.empty())
3159d3ae10eSAlpana Kumari                                     {
316168e20c1SEd Tanous                                         for (const std::pair<
317168e20c1SEd Tanous                                                  std::string,
318168e20c1SEd Tanous                                                  dbus::utility::
319168e20c1SEd Tanous                                                      DbusVariantType>&
3201214b7e7SGunnar Mills                                                  property : properties)
3211abe55efSEd Tanous                                         {
3225fd7ba65SCheng C Yang                                             if (property.first !=
3235fd7ba65SCheng C Yang                                                 "MemorySizeInKB")
3241abe55efSEd Tanous                                             {
3255fd7ba65SCheng C Yang                                                 continue;
3265fd7ba65SCheng C Yang                                             }
3275fd7ba65SCheng C Yang                                             const uint32_t* value =
3288d78b7a9SPatrick Williams                                                 std::get_if<uint32_t>(
3291b6b96c5SEd Tanous                                                     &property.second);
3305fd7ba65SCheng C Yang                                             if (value == nullptr)
3311abe55efSEd Tanous                                             {
3325fd7ba65SCheng C Yang                                                 BMCWEB_LOG_DEBUG
3330fda0f12SGeorge Liu                                                     << "Find incorrect type of MemorySize";
3345fd7ba65SCheng C Yang                                                 continue;
3355fd7ba65SCheng C Yang                                             }
3365fd7ba65SCheng C Yang                                             nlohmann::json& totalMemory =
3370fda0f12SGeorge Liu                                                 aResp->res.jsonValue
3380fda0f12SGeorge Liu                                                     ["MemorySummary"]
3390fda0f12SGeorge Liu                                                     ["TotalSystemMemoryGiB"];
3405fd7ba65SCheng C Yang                                             uint64_t* preValue =
3415fd7ba65SCheng C Yang                                                 totalMemory
3425fd7ba65SCheng C Yang                                                     .get_ptr<uint64_t*>();
3435fd7ba65SCheng C Yang                                             if (preValue == nullptr)
3445fd7ba65SCheng C Yang                                             {
3455fd7ba65SCheng C Yang                                                 continue;
3465fd7ba65SCheng C Yang                                             }
3470fda0f12SGeorge Liu                                             aResp->res.jsonValue
3480fda0f12SGeorge Liu                                                 ["MemorySummary"]
3490fda0f12SGeorge Liu                                                 ["TotalSystemMemoryGiB"] =
3505fd7ba65SCheng C Yang                                                 *value / (1024 * 1024) +
3515fd7ba65SCheng C Yang                                                 *preValue;
3525fd7ba65SCheng C Yang                                             aResp->res
3535fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
3549d3ae10eSAlpana Kumari                                                           ["Status"]["State"] =
3551abe55efSEd Tanous                                                 "Enabled";
356c5b2abe0SLewanczyk, Dawid                                         }
357c5b2abe0SLewanczyk, Dawid                                     }
3589d3ae10eSAlpana Kumari                                     else
3599d3ae10eSAlpana Kumari                                     {
3601e1e598dSJonathan Doman                                         sdbusplus::asio::getProperty<bool>(
3611e1e598dSJonathan Doman                                             *crow::connections::systemBus,
3621e1e598dSJonathan Doman                                             service, path,
3631e1e598dSJonathan Doman                                             "xyz.openbmc_project.State."
3641e1e598dSJonathan Doman                                             "Decorator.OperationalStatus",
3651e1e598dSJonathan Doman                                             "Functional",
3669d3ae10eSAlpana Kumari                                             [aResp](
3679d3ae10eSAlpana Kumari                                                 const boost::system::error_code
368cb13a392SEd Tanous                                                     ec3,
3691e1e598dSJonathan Doman                                                 bool dimmState) {
370cb13a392SEd Tanous                                                 if (ec3)
3719d3ae10eSAlpana Kumari                                                 {
3729d3ae10eSAlpana Kumari                                                     BMCWEB_LOG_ERROR
3730fda0f12SGeorge Liu                                                         << "DBUS response error "
374cb13a392SEd Tanous                                                         << ec3;
3759d3ae10eSAlpana Kumari                                                     return;
3769d3ae10eSAlpana Kumari                                                 }
3779d3ae10eSAlpana Kumari                                                 updateDimmProperties(aResp,
3789d3ae10eSAlpana Kumari                                                                      dimmState);
3791e1e598dSJonathan Doman                                             });
3809d3ae10eSAlpana Kumari                                     }
381c5b2abe0SLewanczyk, Dawid                                 },
38204a258f4SEd Tanous                                 connection.first, path,
3836c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
3846c34de48SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm");
3855bc2dc8eSJames Feist 
3865bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
3871abe55efSEd Tanous                         }
38804a258f4SEd Tanous                         else if (interfaceName ==
38904a258f4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.Cpu")
3901abe55efSEd Tanous                         {
3911abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
39204a258f4SEd Tanous                                 << "Found Cpu, now get its properties.";
39357e8c9beSAlpana Kumari 
39403fbed92SAli Ahmed                             getProcessorSummary(aResp, connection.first, path);
3955bc2dc8eSJames Feist 
3965bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
3971abe55efSEd Tanous                         }
39804a258f4SEd Tanous                         else if (interfaceName ==
39904a258f4SEd Tanous                                  "xyz.openbmc_project.Common.UUID")
4001abe55efSEd Tanous                         {
4011abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
40204a258f4SEd Tanous                                 << "Found UUID, now get its properties.";
40355c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
404168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec3,
405168e20c1SEd Tanous                                         const std::vector<std::pair<
406168e20c1SEd Tanous                                             std::string,
407168e20c1SEd Tanous                                             dbus::utility::DbusVariantType>>&
4081214b7e7SGunnar Mills                                             properties) {
409cb13a392SEd Tanous                                     if (ec3)
4101abe55efSEd Tanous                                     {
4111abe55efSEd Tanous                                         BMCWEB_LOG_DEBUG
412cb13a392SEd Tanous                                             << "DBUS response error " << ec3;
413f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
414c5b2abe0SLewanczyk, Dawid                                         return;
415c5b2abe0SLewanczyk, Dawid                                     }
4166c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
4176c34de48SEd Tanous                                                      << properties.size()
418c5b2abe0SLewanczyk, Dawid                                                      << " UUID properties.";
419168e20c1SEd Tanous                                     for (const std::pair<
420168e20c1SEd Tanous                                              std::string,
421168e20c1SEd Tanous                                              dbus::utility::DbusVariantType>&
4221214b7e7SGunnar Mills                                              property : properties)
4231abe55efSEd Tanous                                     {
42404a258f4SEd Tanous                                         if (property.first == "UUID")
4251abe55efSEd Tanous                                         {
426c5b2abe0SLewanczyk, Dawid                                             const std::string* value =
4278d78b7a9SPatrick Williams                                                 std::get_if<std::string>(
4281b6b96c5SEd Tanous                                                     &property.second);
42904a258f4SEd Tanous 
4301abe55efSEd Tanous                                             if (value != nullptr)
4311abe55efSEd Tanous                                             {
432029573d4SEd Tanous                                                 std::string valueStr = *value;
43304a258f4SEd Tanous                                                 if (valueStr.size() == 32)
4341abe55efSEd Tanous                                                 {
435029573d4SEd Tanous                                                     valueStr.insert(8, 1, '-');
436029573d4SEd Tanous                                                     valueStr.insert(13, 1, '-');
437029573d4SEd Tanous                                                     valueStr.insert(18, 1, '-');
438029573d4SEd Tanous                                                     valueStr.insert(23, 1, '-');
43904a258f4SEd Tanous                                                 }
440029573d4SEd Tanous                                                 BMCWEB_LOG_DEBUG << "UUID = "
44104a258f4SEd Tanous                                                                  << valueStr;
442029573d4SEd Tanous                                                 aResp->res.jsonValue["UUID"] =
44304a258f4SEd Tanous                                                     valueStr;
444c5b2abe0SLewanczyk, Dawid                                             }
445c5b2abe0SLewanczyk, Dawid                                         }
446c5b2abe0SLewanczyk, Dawid                                     }
447c5b2abe0SLewanczyk, Dawid                                 },
44804a258f4SEd Tanous                                 connection.first, path,
4496c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4501abe55efSEd Tanous                                 "xyz.openbmc_project.Common.UUID");
451c5b2abe0SLewanczyk, Dawid                         }
452029573d4SEd Tanous                         else if (interfaceName ==
453029573d4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.System")
4541abe55efSEd Tanous                         {
455029573d4SEd Tanous                             crow::connections::systemBus->async_method_call(
456168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec2,
457168e20c1SEd Tanous                                         const std::vector<std::pair<
458168e20c1SEd Tanous                                             std::string,
459168e20c1SEd Tanous                                             dbus::utility::DbusVariantType>>&
4601214b7e7SGunnar Mills                                             propertiesList) {
461cb13a392SEd Tanous                                     if (ec2)
462029573d4SEd Tanous                                     {
463e4a4b9a9SJames Feist                                         // doesn't have to include this
464e4a4b9a9SJames Feist                                         // interface
465029573d4SEd Tanous                                         return;
466029573d4SEd Tanous                                     }
467698654b6SGunnar Mills                                     BMCWEB_LOG_DEBUG
468698654b6SGunnar Mills                                         << "Got " << propertiesList.size()
469029573d4SEd Tanous                                         << " properties for system";
470168e20c1SEd Tanous                                     for (const std::pair<
471168e20c1SEd Tanous                                              std::string,
472168e20c1SEd Tanous                                              dbus::utility::DbusVariantType>&
4731214b7e7SGunnar Mills                                              property : propertiesList)
474029573d4SEd Tanous                                     {
475fc5afcf9Sbeccabroek                                         const std::string& propertyName =
476fc5afcf9Sbeccabroek                                             property.first;
477fc5afcf9Sbeccabroek                                         if ((propertyName == "PartNumber") ||
478fc5afcf9Sbeccabroek                                             (propertyName == "SerialNumber") ||
479fc5afcf9Sbeccabroek                                             (propertyName == "Manufacturer") ||
4805235d964SSunnySrivastava1984                                             (propertyName == "Model") ||
4815235d964SSunnySrivastava1984                                             (propertyName == "SubModel"))
482fc5afcf9Sbeccabroek                                         {
483029573d4SEd Tanous                                             const std::string* value =
484fc5afcf9Sbeccabroek                                                 std::get_if<std::string>(
485029573d4SEd Tanous                                                     &property.second);
486029573d4SEd Tanous                                             if (value != nullptr)
487029573d4SEd Tanous                                             {
488029573d4SEd Tanous                                                 aResp->res
489fc5afcf9Sbeccabroek                                                     .jsonValue[propertyName] =
490029573d4SEd Tanous                                                     *value;
491029573d4SEd Tanous                                             }
492029573d4SEd Tanous                                         }
493fc5afcf9Sbeccabroek                                     }
494c1e236a6SGunnar Mills 
495cb7e1e7bSAndrew Geissler                                     // Grab the bios version
496f97ddba7SGunnar Mills                                     fw_util::populateFirmwareInformation(
497cb7e1e7bSAndrew Geissler                                         aResp, fw_util::biosPurpose,
49872d566d9SGunnar Mills                                         "BiosVersion", false);
499029573d4SEd Tanous                                 },
500029573d4SEd Tanous                                 connection.first, path,
501029573d4SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
5020fda0f12SGeorge Liu                                 "xyz.openbmc_project.Inventory.Decorator.Asset");
503e4a4b9a9SJames Feist 
5041e1e598dSJonathan Doman                             sdbusplus::asio::getProperty<std::string>(
5051e1e598dSJonathan Doman                                 *crow::connections::systemBus, connection.first,
5061e1e598dSJonathan Doman                                 path,
5071e1e598dSJonathan Doman                                 "xyz.openbmc_project.Inventory.Decorator."
5081e1e598dSJonathan Doman                                 "AssetTag",
5091e1e598dSJonathan Doman                                 "AssetTag",
510168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec2,
5111e1e598dSJonathan Doman                                         const std::string& value) {
512cb13a392SEd Tanous                                     if (ec2)
513e4a4b9a9SJames Feist                                     {
514e4a4b9a9SJames Feist                                         // doesn't have to include this
515e4a4b9a9SJames Feist                                         // interface
516e4a4b9a9SJames Feist                                         return;
517e4a4b9a9SJames Feist                                     }
518e4a4b9a9SJames Feist 
5191e1e598dSJonathan Doman                                     aResp->res.jsonValue["AssetTag"] = value;
5201e1e598dSJonathan Doman                                 });
521029573d4SEd Tanous                         }
522029573d4SEd Tanous                     }
523029573d4SEd Tanous                 }
524c5b2abe0SLewanczyk, Dawid             }
525c5b2abe0SLewanczyk, Dawid         },
526c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
527c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
528c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5296617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
5306617338dSEd Tanous         std::array<const char*, 5>{
5316617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
5326617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
5336617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
5346617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
5356617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
5366617338dSEd Tanous         });
537c5b2abe0SLewanczyk, Dawid }
538c5b2abe0SLewanczyk, Dawid 
539c5b2abe0SLewanczyk, Dawid /**
540c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
541c5b2abe0SLewanczyk, Dawid  *
542c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
543c5b2abe0SLewanczyk, Dawid  *
544c5b2abe0SLewanczyk, Dawid  * @return None.
545c5b2abe0SLewanczyk, Dawid  */
5468d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5471abe55efSEd Tanous {
54855c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5491e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5501e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5511e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5521e1e598dSJonathan Doman         "CurrentHostState",
553c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
5541e1e598dSJonathan Doman                 const std::string& hostState) {
5551abe55efSEd Tanous             if (ec)
5561abe55efSEd Tanous             {
55722228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
55822228c28SAndrew Geissler                 {
55922228c28SAndrew Geissler                     // Service not available, no error, just don't return
56022228c28SAndrew Geissler                     // host state info
56122228c28SAndrew Geissler                     BMCWEB_LOG_DEBUG << "Service not available " << ec;
56222228c28SAndrew Geissler                     return;
56322228c28SAndrew Geissler                 }
56422228c28SAndrew Geissler                 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
565f12894f8SJason M. Bills                 messages::internalError(aResp->res);
566c5b2abe0SLewanczyk, Dawid                 return;
567c5b2abe0SLewanczyk, Dawid             }
5686617338dSEd Tanous 
5691e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Host state: " << hostState;
570c5b2abe0SLewanczyk, Dawid             // Verify Host State
5711e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5721abe55efSEd Tanous             {
57355c7b7a2SEd Tanous                 aResp->res.jsonValue["PowerState"] = "On";
5746617338dSEd Tanous                 aResp->res.jsonValue["Status"]["State"] = "Enabled";
5751abe55efSEd Tanous             }
5761e1e598dSJonathan Doman             else if (hostState ==
5770fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
5788c888608SGunnar Mills             {
5798c888608SGunnar Mills                 aResp->res.jsonValue["PowerState"] = "On";
5808c888608SGunnar Mills                 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
5818c888608SGunnar Mills             }
5821e1e598dSJonathan Doman             else if (hostState ==
5830fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
58483935af9SAndrew Geissler             {
58583935af9SAndrew Geissler                 aResp->res.jsonValue["PowerState"] = "On";
58683935af9SAndrew Geissler                 aResp->res.jsonValue["Status"]["State"] = "InTest";
58783935af9SAndrew Geissler             }
5880fda0f12SGeorge Liu             else if (
5891e1e598dSJonathan Doman                 hostState ==
5900fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5911a2a1437SAndrew Geissler             {
5921a2a1437SAndrew Geissler                 aResp->res.jsonValue["PowerState"] = "PoweringOn";
59315c27bf8SNoah Brewer                 aResp->res.jsonValue["Status"]["State"] = "Starting";
5941a2a1437SAndrew Geissler             }
5950fda0f12SGeorge Liu             else if (
5961e1e598dSJonathan Doman                 hostState ==
5970fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5981a2a1437SAndrew Geissler             {
5991a2a1437SAndrew Geissler                 aResp->res.jsonValue["PowerState"] = "PoweringOff";
6001a2a1437SAndrew Geissler                 aResp->res.jsonValue["Status"]["State"] = "Disabled";
6011a2a1437SAndrew Geissler             }
6021abe55efSEd Tanous             else
6031abe55efSEd Tanous             {
60455c7b7a2SEd Tanous                 aResp->res.jsonValue["PowerState"] = "Off";
6056617338dSEd Tanous                 aResp->res.jsonValue["Status"]["State"] = "Disabled";
606c5b2abe0SLewanczyk, Dawid             }
6071e1e598dSJonathan Doman         });
608c5b2abe0SLewanczyk, Dawid }
609c5b2abe0SLewanczyk, Dawid 
610c5b2abe0SLewanczyk, Dawid /**
611786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
612491d8ee7SSantosh Puranik  *
613491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
614491d8ee7SSantosh Puranik  *
615491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
616491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
617491d8ee7SSantosh Puranik  */
61823a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
619491d8ee7SSantosh Puranik {
620491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
621491d8ee7SSantosh Puranik     {
622491d8ee7SSantosh Puranik         return "None";
623491d8ee7SSantosh Puranik     }
6243174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
625491d8ee7SSantosh Puranik     {
626491d8ee7SSantosh Puranik         return "Hdd";
627491d8ee7SSantosh Puranik     }
6283174e4dfSEd Tanous     if (dbusSource ==
629a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
630491d8ee7SSantosh Puranik     {
631491d8ee7SSantosh Puranik         return "Cd";
632491d8ee7SSantosh Puranik     }
6333174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
634491d8ee7SSantosh Puranik     {
635491d8ee7SSantosh Puranik         return "Pxe";
636491d8ee7SSantosh Puranik     }
6373174e4dfSEd Tanous     if (dbusSource ==
638944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6399f16b2c1SJennifer Lee     {
6409f16b2c1SJennifer Lee         return "Usb";
6419f16b2c1SJennifer Lee     }
642491d8ee7SSantosh Puranik     return "";
643491d8ee7SSantosh Puranik }
644491d8ee7SSantosh Puranik 
645491d8ee7SSantosh Puranik /**
646cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
647cd9a4666SKonstantin Aladyshev  *
648cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
649cd9a4666SKonstantin Aladyshev  *
650cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
651cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
652cd9a4666SKonstantin Aladyshev  */
653cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
654cd9a4666SKonstantin Aladyshev {
655cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
656cd9a4666SKonstantin Aladyshev     {
657cd9a4666SKonstantin Aladyshev         return "Legacy";
658cd9a4666SKonstantin Aladyshev     }
659cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
660cd9a4666SKonstantin Aladyshev     {
661cd9a4666SKonstantin Aladyshev         return "UEFI";
662cd9a4666SKonstantin Aladyshev     }
663cd9a4666SKonstantin Aladyshev     return "";
664cd9a4666SKonstantin Aladyshev }
665cd9a4666SKonstantin Aladyshev 
666cd9a4666SKonstantin Aladyshev /**
667786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
668491d8ee7SSantosh Puranik  *
669491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
670491d8ee7SSantosh Puranik  *
671491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
672491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
673491d8ee7SSantosh Puranik  */
67423a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
675491d8ee7SSantosh Puranik {
676491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
677491d8ee7SSantosh Puranik     {
678491d8ee7SSantosh Puranik         return "None";
679491d8ee7SSantosh Puranik     }
6803174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
681491d8ee7SSantosh Puranik     {
682491d8ee7SSantosh Puranik         return "Diags";
683491d8ee7SSantosh Puranik     }
6843174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
685491d8ee7SSantosh Puranik     {
686491d8ee7SSantosh Puranik         return "BiosSetup";
687491d8ee7SSantosh Puranik     }
688491d8ee7SSantosh Puranik     return "";
689491d8ee7SSantosh Puranik }
690491d8ee7SSantosh Puranik 
691491d8ee7SSantosh Puranik /**
692e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
693e43914b3SAndrew Geissler  *
694e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
695e43914b3SAndrew Geissler  *
696e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
697e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
698e43914b3SAndrew Geissler  */
699e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
700e43914b3SAndrew Geissler {
701e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
702e43914b3SAndrew Geissler     // enum
703e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
704e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
705e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
706e43914b3SAndrew Geissler     {
707e43914b3SAndrew Geissler         rfBpLastState = "None";
708e43914b3SAndrew Geissler     }
709e43914b3SAndrew Geissler     else if (dbusBootProgress ==
710e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
711e43914b3SAndrew Geissler              "PrimaryProcInit")
712e43914b3SAndrew Geissler     {
713e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
714e43914b3SAndrew Geissler     }
715e43914b3SAndrew Geissler     else if (dbusBootProgress ==
716e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
717e43914b3SAndrew Geissler              "BusInit")
718e43914b3SAndrew Geissler     {
719e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
720e43914b3SAndrew Geissler     }
721e43914b3SAndrew Geissler     else if (dbusBootProgress ==
722e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
723e43914b3SAndrew Geissler              "MemoryInit")
724e43914b3SAndrew Geissler     {
725e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
726e43914b3SAndrew Geissler     }
727e43914b3SAndrew Geissler     else if (dbusBootProgress ==
728e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
729e43914b3SAndrew Geissler              "SecondaryProcInit")
730e43914b3SAndrew Geissler     {
731e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
732e43914b3SAndrew Geissler     }
733e43914b3SAndrew Geissler     else if (dbusBootProgress ==
734e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
735e43914b3SAndrew Geissler              "PCIInit")
736e43914b3SAndrew Geissler     {
737e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
738e43914b3SAndrew Geissler     }
739e43914b3SAndrew Geissler     else if (dbusBootProgress ==
740e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
741e43914b3SAndrew Geissler              "SystemSetup")
742e43914b3SAndrew Geissler     {
743e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
744e43914b3SAndrew Geissler     }
745e43914b3SAndrew Geissler     else if (dbusBootProgress ==
746e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
747e43914b3SAndrew Geissler              "SystemInitComplete")
748e43914b3SAndrew Geissler     {
749e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
750e43914b3SAndrew Geissler     }
751e43914b3SAndrew Geissler     else if (dbusBootProgress ==
752e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
753e43914b3SAndrew Geissler              "OSStart")
754e43914b3SAndrew Geissler     {
755e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
756e43914b3SAndrew Geissler     }
757e43914b3SAndrew Geissler     else if (dbusBootProgress ==
758e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
759e43914b3SAndrew Geissler              "OSRunning")
760e43914b3SAndrew Geissler     {
761e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
762e43914b3SAndrew Geissler     }
763e43914b3SAndrew Geissler     else
764e43914b3SAndrew Geissler     {
765e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
766e43914b3SAndrew Geissler                          << dbusBootProgress;
767e43914b3SAndrew Geissler         // Just return the default
768e43914b3SAndrew Geissler     }
769e43914b3SAndrew Geissler     return rfBpLastState;
770e43914b3SAndrew Geissler }
771e43914b3SAndrew Geissler 
772e43914b3SAndrew Geissler /**
773786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
774491d8ee7SSantosh Puranik  *
775491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
776944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
777944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
778491d8ee7SSantosh Puranik  *
779944ffaf9SJohnathan Mantey  * @return Integer error code.
780491d8ee7SSantosh Puranik  */
7818d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
782944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
783944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
784491d8ee7SSantosh Puranik {
785c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
786c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
787944ffaf9SJohnathan Mantey 
788491d8ee7SSantosh Puranik     if (rfSource == "None")
789491d8ee7SSantosh Puranik     {
790944ffaf9SJohnathan Mantey         return 0;
791491d8ee7SSantosh Puranik     }
7923174e4dfSEd Tanous     if (rfSource == "Pxe")
793491d8ee7SSantosh Puranik     {
794944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
795944ffaf9SJohnathan Mantey     }
796944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
797944ffaf9SJohnathan Mantey     {
798944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
799944ffaf9SJohnathan Mantey     }
800944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
801944ffaf9SJohnathan Mantey     {
802944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
803944ffaf9SJohnathan Mantey     }
804944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
805944ffaf9SJohnathan Mantey     {
806944ffaf9SJohnathan Mantey         bootSource =
807944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
808944ffaf9SJohnathan Mantey     }
809944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
810944ffaf9SJohnathan Mantey     {
811944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
812491d8ee7SSantosh Puranik     }
8139f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8149f16b2c1SJennifer Lee     {
815944ffaf9SJohnathan Mantey         bootSource =
816944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8179f16b2c1SJennifer Lee     }
818491d8ee7SSantosh Puranik     else
819491d8ee7SSantosh Puranik     {
8200fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8210fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
822944ffaf9SJohnathan Mantey             << bootSource;
823944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
824944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
825944ffaf9SJohnathan Mantey         return -1;
826491d8ee7SSantosh Puranik     }
827944ffaf9SJohnathan Mantey     return 0;
828491d8ee7SSantosh Puranik }
8291981771bSAli Ahmed 
830978b8803SAndrew Geissler /**
831978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
832978b8803SAndrew Geissler  *
833978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
834978b8803SAndrew Geissler  *
835978b8803SAndrew Geissler  * @return None.
836978b8803SAndrew Geissler  */
8378d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
838978b8803SAndrew Geissler {
8391e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8401e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8411e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8421e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
843978b8803SAndrew Geissler         [aResp](const boost::system::error_code ec,
8441e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
845978b8803SAndrew Geissler             if (ec)
846978b8803SAndrew Geissler             {
847978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
848978b8803SAndrew Geissler                 // not found
849978b8803SAndrew Geissler                 return;
850978b8803SAndrew Geissler             }
851978b8803SAndrew Geissler 
8521e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
853978b8803SAndrew Geissler 
854e43914b3SAndrew Geissler             aResp->res.jsonValue["BootProgress"]["LastState"] =
855e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
8561e1e598dSJonathan Doman         });
857978b8803SAndrew Geissler }
858491d8ee7SSantosh Puranik 
859491d8ee7SSantosh Puranik /**
860c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
861cd9a4666SKonstantin Aladyshev  *
862cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
863cd9a4666SKonstantin Aladyshev  *
864cd9a4666SKonstantin Aladyshev  * @return None.
865cd9a4666SKonstantin Aladyshev  */
866cd9a4666SKonstantin Aladyshev 
867c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
868cd9a4666SKonstantin Aladyshev {
8691e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8701e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
8711e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8721e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
873cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
8741e1e598dSJonathan Doman                 const std::string& bootType) {
875cd9a4666SKonstantin Aladyshev             if (ec)
876cd9a4666SKonstantin Aladyshev             {
877cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
878cd9a4666SKonstantin Aladyshev                 return;
879cd9a4666SKonstantin Aladyshev             }
880cd9a4666SKonstantin Aladyshev 
8811e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
882cd9a4666SKonstantin Aladyshev 
8830fda0f12SGeorge Liu             aResp->res
8840fda0f12SGeorge Liu                 .jsonValue["Boot"]
8850fda0f12SGeorge Liu                           ["BootSourceOverrideMode@Redfish.AllowableValues"] = {
8860fda0f12SGeorge Liu                 "Legacy", "UEFI"};
887cd9a4666SKonstantin Aladyshev 
8881e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
889cd9a4666SKonstantin Aladyshev             if (rfType.empty())
890cd9a4666SKonstantin Aladyshev             {
891cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
892cd9a4666SKonstantin Aladyshev                 return;
893cd9a4666SKonstantin Aladyshev             }
894cd9a4666SKonstantin Aladyshev 
895cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
8961e1e598dSJonathan Doman         });
897cd9a4666SKonstantin Aladyshev }
898cd9a4666SKonstantin Aladyshev 
899cd9a4666SKonstantin Aladyshev /**
900c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
901491d8ee7SSantosh Puranik  *
902491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
903491d8ee7SSantosh Puranik  *
904491d8ee7SSantosh Puranik  * @return None.
905491d8ee7SSantosh Puranik  */
906c21865c4SKonstantin Aladyshev 
907c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
908491d8ee7SSantosh Puranik {
9091e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9101e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9111e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9121e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
913c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
9141e1e598dSJonathan Doman                 const std::string& bootModeStr) {
915491d8ee7SSantosh Puranik             if (ec)
916491d8ee7SSantosh Puranik             {
917491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
918491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
919491d8ee7SSantosh Puranik                 return;
920491d8ee7SSantosh Puranik             }
921491d8ee7SSantosh Puranik 
9221e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
923491d8ee7SSantosh Puranik 
9240fda0f12SGeorge Liu             aResp->res
9250fda0f12SGeorge Liu                 .jsonValue["Boot"]
9260fda0f12SGeorge Liu                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
9270fda0f12SGeorge Liu                 {"None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
928491d8ee7SSantosh Puranik 
9291e1e598dSJonathan Doman             if (bootModeStr !=
930491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
931491d8ee7SSantosh Puranik             {
9321e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
933491d8ee7SSantosh Puranik                 if (!rfMode.empty())
934491d8ee7SSantosh Puranik                 {
935491d8ee7SSantosh Puranik                     aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
936491d8ee7SSantosh Puranik                         rfMode;
937491d8ee7SSantosh Puranik                 }
938491d8ee7SSantosh Puranik             }
9391e1e598dSJonathan Doman         });
940491d8ee7SSantosh Puranik }
941491d8ee7SSantosh Puranik 
942491d8ee7SSantosh Puranik /**
943c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
944491d8ee7SSantosh Puranik  *
945491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
946491d8ee7SSantosh Puranik  *
947491d8ee7SSantosh Puranik  * @return None.
948491d8ee7SSantosh Puranik  */
949c21865c4SKonstantin Aladyshev 
950c21865c4SKonstantin Aladyshev inline void
951c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
952491d8ee7SSantosh Puranik {
9531e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9541e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9551e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9561e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
957c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
9581e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
959491d8ee7SSantosh Puranik             if (ec)
960491d8ee7SSantosh Puranik             {
961491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
962491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
963491d8ee7SSantosh Puranik                 return;
964491d8ee7SSantosh Puranik             }
965491d8ee7SSantosh Puranik 
9661e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
967491d8ee7SSantosh Puranik 
9681e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
969491d8ee7SSantosh Puranik             if (!rfSource.empty())
970491d8ee7SSantosh Puranik             {
971491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
972491d8ee7SSantosh Puranik                     rfSource;
973491d8ee7SSantosh Puranik             }
974cd9a4666SKonstantin Aladyshev 
975cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
976cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
977c21865c4SKonstantin Aladyshev             getBootOverrideMode(aResp);
9781e1e598dSJonathan Doman         });
979491d8ee7SSantosh Puranik }
980491d8ee7SSantosh Puranik 
981491d8ee7SSantosh Puranik /**
982c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
983c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
984c21865c4SKonstantin Aladyshev  * state
985491d8ee7SSantosh Puranik  *
986491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
987491d8ee7SSantosh Puranik  *
988491d8ee7SSantosh Puranik  * @return None.
989491d8ee7SSantosh Puranik  */
990491d8ee7SSantosh Puranik 
991c21865c4SKonstantin Aladyshev inline void
992c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
993c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
994c21865c4SKonstantin Aladyshev {
995c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
996c21865c4SKonstantin Aladyshev     {
997c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
998c21865c4SKonstantin Aladyshev         return;
999c21865c4SKonstantin Aladyshev     }
1000c21865c4SKonstantin Aladyshev 
1001c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1002c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10031e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10041e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10051e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10061e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10071e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
1008491d8ee7SSantosh Puranik             if (ec)
1009491d8ee7SSantosh Puranik             {
1010491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1011c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1012491d8ee7SSantosh Puranik                 return;
1013491d8ee7SSantosh Puranik             }
1014491d8ee7SSantosh Puranik 
1015c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1016c21865c4SKonstantin Aladyshev             {
1017c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1018c21865c4SKonstantin Aladyshev                     "Once";
1019c21865c4SKonstantin Aladyshev             }
1020c21865c4SKonstantin Aladyshev             else
1021c21865c4SKonstantin Aladyshev             {
1022c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1023c21865c4SKonstantin Aladyshev                     "Continuous";
1024c21865c4SKonstantin Aladyshev             }
10251e1e598dSJonathan Doman         });
1026491d8ee7SSantosh Puranik }
1027491d8ee7SSantosh Puranik 
1028491d8ee7SSantosh Puranik /**
1029c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1030c21865c4SKonstantin Aladyshev  *
1031c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1032c21865c4SKonstantin Aladyshev  *
1033c21865c4SKonstantin Aladyshev  * @return None.
1034c21865c4SKonstantin Aladyshev  */
1035c21865c4SKonstantin Aladyshev 
1036c21865c4SKonstantin Aladyshev inline void
1037c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1038c21865c4SKonstantin Aladyshev {
10391e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10401e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10411e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10421e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1043c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
10441e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1045c21865c4SKonstantin Aladyshev             if (ec)
1046c21865c4SKonstantin Aladyshev             {
1047c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1048c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1049c21865c4SKonstantin Aladyshev                 return;
1050c21865c4SKonstantin Aladyshev             }
1051c21865c4SKonstantin Aladyshev 
10521e1e598dSJonathan Doman             processBootOverrideEnable(aResp, bootOverrideEnable);
10531e1e598dSJonathan Doman         });
1054c21865c4SKonstantin Aladyshev }
1055c21865c4SKonstantin Aladyshev 
1056c21865c4SKonstantin Aladyshev /**
1057c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1058c21865c4SKonstantin Aladyshev  *
1059c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1060c21865c4SKonstantin Aladyshev  *
1061c21865c4SKonstantin Aladyshev  * @return None.
1062c21865c4SKonstantin Aladyshev  */
1063c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1064c21865c4SKonstantin Aladyshev {
1065c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1066c21865c4SKonstantin Aladyshev 
1067c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1068c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1069c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1070c21865c4SKonstantin Aladyshev }
1071c21865c4SKonstantin Aladyshev 
1072c21865c4SKonstantin Aladyshev /**
1073c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1074c0557e1aSGunnar Mills  *
1075c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1076c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1077c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1078c0557e1aSGunnar Mills  * last power operation time.
1079c0557e1aSGunnar Mills  *
1080c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1081c0557e1aSGunnar Mills  *
1082c0557e1aSGunnar Mills  * @return None.
1083c0557e1aSGunnar Mills  */
10848d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1085c0557e1aSGunnar Mills {
1086c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1087c0557e1aSGunnar Mills 
10881e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
10891e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
10901e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
10911e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
10921e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
1093c0557e1aSGunnar Mills             if (ec)
1094c0557e1aSGunnar Mills             {
1095c0557e1aSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1096c0557e1aSGunnar Mills                 return;
1097c0557e1aSGunnar Mills             }
1098c0557e1aSGunnar Mills 
1099c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1100c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11011e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1102c0557e1aSGunnar Mills 
1103c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1104c0557e1aSGunnar Mills             aResp->res.jsonValue["LastResetTime"] =
11051d8782e7SNan Zhou                 crow::utility::getDateTimeUint(lastResetTimeStamp);
11061e1e598dSJonathan Doman         });
1107c0557e1aSGunnar Mills }
1108c0557e1aSGunnar Mills 
1109c0557e1aSGunnar Mills /**
11106bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11116bd5a8d2SGunnar Mills  *
11126bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11136bd5a8d2SGunnar Mills  *
11146bd5a8d2SGunnar Mills  * @return None.
11156bd5a8d2SGunnar Mills  */
11168d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11176bd5a8d2SGunnar Mills {
11186bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
11196bd5a8d2SGunnar Mills 
11201e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11211e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11221e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
11231e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
11241e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
11256bd5a8d2SGunnar Mills             if (ec)
11266bd5a8d2SGunnar Mills             {
11276bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
11286bd5a8d2SGunnar Mills                 return;
11296bd5a8d2SGunnar Mills             }
11306bd5a8d2SGunnar Mills 
11311e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1132e05aec50SEd Tanous             if (autoRebootEnabled)
11336bd5a8d2SGunnar Mills             {
11346bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11356bd5a8d2SGunnar Mills                     "RetryAttempts";
11366bd5a8d2SGunnar Mills                 // If AutomaticRetry (AutoReboot) is enabled see how many
11376bd5a8d2SGunnar Mills                 // attempts are left
11381e1e598dSJonathan Doman                 sdbusplus::asio::getProperty<uint32_t>(
11391e1e598dSJonathan Doman                     *crow::connections::systemBus,
11401e1e598dSJonathan Doman                     "xyz.openbmc_project.State.Host",
11411e1e598dSJonathan Doman                     "/xyz/openbmc_project/state/host0",
11421e1e598dSJonathan Doman                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
11431e1e598dSJonathan Doman                     "AttemptsLeft",
1144cb13a392SEd Tanous                     [aResp](const boost::system::error_code ec2,
1145914e2d5dSEd Tanous                             const uint32_t autoRebootAttemptsLeft) {
1146cb13a392SEd Tanous                         if (ec2)
11476bd5a8d2SGunnar Mills                         {
1148cb13a392SEd Tanous                             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
11496bd5a8d2SGunnar Mills                             return;
11506bd5a8d2SGunnar Mills                         }
11516bd5a8d2SGunnar Mills 
11526bd5a8d2SGunnar Mills                         BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
11531e1e598dSJonathan Doman                                          << autoRebootAttemptsLeft;
11546bd5a8d2SGunnar Mills 
11556bd5a8d2SGunnar Mills                         aResp->res
11566bd5a8d2SGunnar Mills                             .jsonValue["Boot"]
11576bd5a8d2SGunnar Mills                                       ["RemainingAutomaticRetryAttempts"] =
11581e1e598dSJonathan Doman                             autoRebootAttemptsLeft;
11591e1e598dSJonathan Doman                     });
11606bd5a8d2SGunnar Mills             }
11616bd5a8d2SGunnar Mills             else
11626bd5a8d2SGunnar Mills             {
11636bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11646bd5a8d2SGunnar Mills                     "Disabled";
11656bd5a8d2SGunnar Mills             }
11666bd5a8d2SGunnar Mills 
11676bd5a8d2SGunnar Mills             // Not on D-Bus. Hardcoded here:
11686bd5a8d2SGunnar Mills             // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
11696bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
117069f35306SGunnar Mills 
117169f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
117269f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
117369f35306SGunnar Mills             // RetryAttempts.
11740fda0f12SGeorge Liu             aResp->res
11750fda0f12SGeorge Liu                 .jsonValue["Boot"]
11760fda0f12SGeorge Liu                           ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
11770fda0f12SGeorge Liu                 "Disabled", "RetryAttempts"};
11781e1e598dSJonathan Doman         });
11796bd5a8d2SGunnar Mills }
11806bd5a8d2SGunnar Mills 
11816bd5a8d2SGunnar Mills /**
1182c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1183c6a620f2SGeorge Liu  *
1184c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1185c6a620f2SGeorge Liu  *
1186c6a620f2SGeorge Liu  * @return None.
1187c6a620f2SGeorge Liu  */
11888d1b46d7Szhanghch05 inline void
11898d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1190c6a620f2SGeorge Liu {
1191c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1192c6a620f2SGeorge Liu 
11931e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
11941e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11951e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
11961e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
11971e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, const std::string& policy) {
1198c6a620f2SGeorge Liu             if (ec)
1199c6a620f2SGeorge Liu             {
1200c6a620f2SGeorge Liu                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1201c6a620f2SGeorge Liu                 return;
1202c6a620f2SGeorge Liu             }
1203c6a620f2SGeorge Liu 
12040fda0f12SGeorge Liu             const boost::container::flat_map<std::string, std::string> policyMaps = {
12050fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1206c6a620f2SGeorge Liu                  "AlwaysOn"},
12070fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1208c6a620f2SGeorge Liu                  "AlwaysOff"},
12090fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1210*4ed47cb8SMatthew Barth                  "LastState"},
1211*4ed47cb8SMatthew Barth                 // Return `AlwaysOff` when power restore policy set to "None"
1212*4ed47cb8SMatthew Barth                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
1213*4ed47cb8SMatthew Barth                  "AlwaysOff"}};
1214c6a620f2SGeorge Liu 
12151e1e598dSJonathan Doman             auto policyMapsIt = policyMaps.find(policy);
1216c6a620f2SGeorge Liu             if (policyMapsIt == policyMaps.end())
1217c6a620f2SGeorge Liu             {
1218c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1219c6a620f2SGeorge Liu                 return;
1220c6a620f2SGeorge Liu             }
1221c6a620f2SGeorge Liu 
1222c6a620f2SGeorge Liu             aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
12231e1e598dSJonathan Doman         });
1224c6a620f2SGeorge Liu }
1225c6a620f2SGeorge Liu 
1226c6a620f2SGeorge Liu /**
12271981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
12281981771bSAli Ahmed  * TPM is required for booting the host.
12291981771bSAli Ahmed  *
12301981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
12311981771bSAli Ahmed  *
12321981771bSAli Ahmed  * @return None.
12331981771bSAli Ahmed  */
12341981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
12351981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12361981771bSAli Ahmed {
12371981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
12381981771bSAli Ahmed 
12391981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
12401981771bSAli Ahmed         [aResp](
12411981771bSAli Ahmed             const boost::system::error_code ec,
12421981771bSAli Ahmed             std::vector<std::pair<
12431981771bSAli Ahmed                 std::string,
12441981771bSAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
12451981771bSAli Ahmed                 subtree) {
12461981771bSAli Ahmed             if (ec)
12471981771bSAli Ahmed             {
12481981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
12491981771bSAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
12501981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
12511981771bSAli Ahmed                 // error occurs
12521981771bSAli Ahmed                 return;
12531981771bSAli Ahmed             }
125426f6976fSEd Tanous             if (subtree.empty())
12551981771bSAli Ahmed             {
12561981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
12571981771bSAli Ahmed                 // if there is no instance found
12581981771bSAli Ahmed                 return;
12591981771bSAli Ahmed             }
12601981771bSAli Ahmed 
12611981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
12621981771bSAli Ahmed             if (subtree.size() > 1)
12631981771bSAli Ahmed             {
12641981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
12651981771bSAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
12661981771bSAli Ahmed                     << subtree.size();
12671981771bSAli Ahmed                 // Throw an internal Error and return
12681981771bSAli Ahmed                 messages::internalError(aResp->res);
12691981771bSAli Ahmed                 return;
12701981771bSAli Ahmed             }
12711981771bSAli Ahmed 
12721981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
12731981771bSAli Ahmed             // field
12741981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
12751981771bSAli Ahmed             {
12761981771bSAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
12771981771bSAli Ahmed                 messages::internalError(aResp->res);
12781981771bSAli Ahmed                 return;
12791981771bSAli Ahmed             }
12801981771bSAli Ahmed 
12811981771bSAli Ahmed             const std::string& path = subtree[0].first;
12821981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
12831981771bSAli Ahmed 
12841981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
12851e1e598dSJonathan Doman             sdbusplus::asio::getProperty<bool>(
12861e1e598dSJonathan Doman                 *crow::connections::systemBus, serv, path,
12871e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
12881e1e598dSJonathan Doman                 [aResp](const boost::system::error_code ec, bool tpmRequired) {
12891981771bSAli Ahmed                     if (ec)
12901981771bSAli Ahmed                     {
12911981771bSAli Ahmed                         BMCWEB_LOG_DEBUG
12921981771bSAli Ahmed                             << "D-BUS response error on TPM.Policy Get" << ec;
12931981771bSAli Ahmed                         messages::internalError(aResp->res);
12941981771bSAli Ahmed                         return;
12951981771bSAli Ahmed                     }
12961981771bSAli Ahmed 
12971e1e598dSJonathan Doman                     if (tpmRequired)
12981981771bSAli Ahmed                     {
12991981771bSAli Ahmed                         aResp->res
13001981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
13011981771bSAli Ahmed                             "Required";
13021981771bSAli Ahmed                     }
13031981771bSAli Ahmed                     else
13041981771bSAli Ahmed                     {
13051981771bSAli Ahmed                         aResp->res
13061981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
13071981771bSAli Ahmed                             "Disabled";
13081981771bSAli Ahmed                     }
13091e1e598dSJonathan Doman                 });
13101981771bSAli Ahmed         },
13111981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
13121981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
13131981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
13141981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
13151981771bSAli Ahmed }
13161981771bSAli Ahmed 
13171981771bSAli Ahmed /**
13181c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
13191c05dae3SAli Ahmed  * TPM is required for booting the host.
13201c05dae3SAli Ahmed  *
13211c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
13221c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
13231c05dae3SAli Ahmed  *
13241c05dae3SAli Ahmed  * @return None.
13251c05dae3SAli Ahmed  */
13261c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
13271c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
13281c05dae3SAli Ahmed {
13291c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
13301c05dae3SAli Ahmed 
13311c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
13321c05dae3SAli Ahmed         [aResp, tpmRequired](
13331c05dae3SAli Ahmed             const boost::system::error_code ec,
13341c05dae3SAli Ahmed             std::vector<std::pair<
13351c05dae3SAli Ahmed                 std::string,
13361c05dae3SAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
13371c05dae3SAli Ahmed                 subtree) {
13381c05dae3SAli Ahmed             if (ec)
13391c05dae3SAli Ahmed             {
13401c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
13411c05dae3SAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
13421c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13431c05dae3SAli Ahmed                 return;
13441c05dae3SAli Ahmed             }
134526f6976fSEd Tanous             if (subtree.empty())
13461c05dae3SAli Ahmed             {
13471c05dae3SAli Ahmed                 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
13481c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
13491c05dae3SAli Ahmed                 return;
13501c05dae3SAli Ahmed             }
13511c05dae3SAli Ahmed 
13521c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
13531c05dae3SAli Ahmed             if (subtree.size() > 1)
13541c05dae3SAli Ahmed             {
13551c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
13561c05dae3SAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
13571c05dae3SAli Ahmed                     << subtree.size();
13581c05dae3SAli Ahmed                 // Throw an internal Error and return
13591c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13601c05dae3SAli Ahmed                 return;
13611c05dae3SAli Ahmed             }
13621c05dae3SAli Ahmed 
13631c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
13641c05dae3SAli Ahmed             // field
13651c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13661c05dae3SAli Ahmed             {
13671c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13681c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13691c05dae3SAli Ahmed                 return;
13701c05dae3SAli Ahmed             }
13711c05dae3SAli Ahmed 
13721c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
13731c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
13741c05dae3SAli Ahmed 
13751c05dae3SAli Ahmed             if (serv.empty())
13761c05dae3SAli Ahmed             {
13771c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
13781c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13791c05dae3SAli Ahmed                 return;
13801c05dae3SAli Ahmed             }
13811c05dae3SAli Ahmed 
13821c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
13831c05dae3SAli Ahmed             crow::connections::systemBus->async_method_call(
13841c05dae3SAli Ahmed                 [aResp](const boost::system::error_code ec) {
13851c05dae3SAli Ahmed                     if (ec)
13861c05dae3SAli Ahmed                     {
13870fda0f12SGeorge Liu                         BMCWEB_LOG_DEBUG
13880fda0f12SGeorge Liu                             << "DBUS response error: Set TrustedModuleRequiredToBoot"
13891c05dae3SAli Ahmed                             << ec;
13901c05dae3SAli Ahmed                         messages::internalError(aResp->res);
13911c05dae3SAli Ahmed                         return;
13921c05dae3SAli Ahmed                     }
13931c05dae3SAli Ahmed                     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
13941c05dae3SAli Ahmed                 },
13951c05dae3SAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Set",
13961c05dae3SAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1397168e20c1SEd Tanous                 dbus::utility::DbusVariantType(tpmRequired));
13981c05dae3SAli Ahmed         },
13991c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
14001c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
14011c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
14021c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
14031c05dae3SAli Ahmed }
14041c05dae3SAli Ahmed 
14051c05dae3SAli Ahmed /**
1406491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1407491d8ee7SSantosh Puranik  *
1408491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1409cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1410cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1411cd9a4666SKonstantin Aladyshev  */
1412cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1413cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1414cd9a4666SKonstantin Aladyshev {
1415c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1416cd9a4666SKonstantin Aladyshev 
1417c21865c4SKonstantin Aladyshev     if (!bootType)
1418cd9a4666SKonstantin Aladyshev     {
1419c21865c4SKonstantin Aladyshev         return;
1420c21865c4SKonstantin Aladyshev     }
1421c21865c4SKonstantin Aladyshev 
1422cd9a4666SKonstantin Aladyshev     // Source target specified
1423cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1424cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1425cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1426cd9a4666SKonstantin Aladyshev     {
1427cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1428cd9a4666SKonstantin Aladyshev     }
1429cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1430cd9a4666SKonstantin Aladyshev     {
1431cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1432cd9a4666SKonstantin Aladyshev     }
1433cd9a4666SKonstantin Aladyshev     else
1434cd9a4666SKonstantin Aladyshev     {
1435cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1436cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1437cd9a4666SKonstantin Aladyshev                          << *bootType;
1438cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1439cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1440cd9a4666SKonstantin Aladyshev         return;
1441cd9a4666SKonstantin Aladyshev     }
1442cd9a4666SKonstantin Aladyshev 
1443cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1444cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1445cd9a4666SKonstantin Aladyshev 
1446cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1447c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1448cd9a4666SKonstantin Aladyshev             if (ec)
1449cd9a4666SKonstantin Aladyshev             {
1450cd9a4666SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1451cd9a4666SKonstantin Aladyshev                 if (ec.value() == boost::asio::error::host_unreachable)
1452cd9a4666SKonstantin Aladyshev                 {
1453cd9a4666SKonstantin Aladyshev                     messages::resourceNotFound(aResp->res, "Set", "BootType");
1454cd9a4666SKonstantin Aladyshev                     return;
1455cd9a4666SKonstantin Aladyshev                 }
1456cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
1457cd9a4666SKonstantin Aladyshev                 return;
1458cd9a4666SKonstantin Aladyshev             }
1459cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type update done.";
1460cd9a4666SKonstantin Aladyshev         },
1461c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1462c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1463cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1464cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1465168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1466cd9a4666SKonstantin Aladyshev }
1467cd9a4666SKonstantin Aladyshev 
1468cd9a4666SKonstantin Aladyshev /**
1469cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1470cd9a4666SKonstantin Aladyshev  *
1471cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1472c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1473c21865c4SKonstantin Aladyshev  * @return Integer error code.
1474c21865c4SKonstantin Aladyshev  */
1475c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1476c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1477c21865c4SKonstantin Aladyshev {
1478c21865c4SKonstantin Aladyshev     if (!bootEnable)
1479c21865c4SKonstantin Aladyshev     {
1480c21865c4SKonstantin Aladyshev         return;
1481c21865c4SKonstantin Aladyshev     }
1482c21865c4SKonstantin Aladyshev     // Source target specified
1483c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1484c21865c4SKonstantin Aladyshev 
1485c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1486c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1487c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1488c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1489c21865c4SKonstantin Aladyshev     {
1490c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1491c21865c4SKonstantin Aladyshev     }
1492c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1493c21865c4SKonstantin Aladyshev     {
1494c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1495c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1496c21865c4SKonstantin Aladyshev     }
1497c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1498c21865c4SKonstantin Aladyshev     {
1499c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1500c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1501c21865c4SKonstantin Aladyshev     }
1502c21865c4SKonstantin Aladyshev     else
1503c21865c4SKonstantin Aladyshev     {
15040fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
15050fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1506c21865c4SKonstantin Aladyshev             << *bootEnable;
1507c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1508c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1509c21865c4SKonstantin Aladyshev         return;
1510c21865c4SKonstantin Aladyshev     }
1511c21865c4SKonstantin Aladyshev 
1512c21865c4SKonstantin Aladyshev     // Act on validated parameters
1513c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1514c21865c4SKonstantin Aladyshev 
1515c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1516c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1517c21865c4SKonstantin Aladyshev             if (ec)
1518c21865c4SKonstantin Aladyshev             {
1519c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1520c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1521c21865c4SKonstantin Aladyshev                 return;
1522c21865c4SKonstantin Aladyshev             }
1523c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1524c21865c4SKonstantin Aladyshev         },
1525c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1526c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1527c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1528c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1529168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1530c21865c4SKonstantin Aladyshev 
1531c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1532c21865c4SKonstantin Aladyshev     {
1533c21865c4SKonstantin Aladyshev         return;
1534c21865c4SKonstantin Aladyshev     }
1535c21865c4SKonstantin Aladyshev 
1536c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1537c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1538c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1539c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1540c21865c4SKonstantin Aladyshev 
1541c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1542c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1543c21865c4SKonstantin Aladyshev             if (ec)
1544c21865c4SKonstantin Aladyshev             {
1545c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1546c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1547c21865c4SKonstantin Aladyshev                 return;
1548c21865c4SKonstantin Aladyshev             }
1549c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1550c21865c4SKonstantin Aladyshev         },
1551c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1552c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1553c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1554c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1555168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1556c21865c4SKonstantin Aladyshev }
1557c21865c4SKonstantin Aladyshev 
1558c21865c4SKonstantin Aladyshev /**
1559c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1560c21865c4SKonstantin Aladyshev  *
1561c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1562491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1563491d8ee7SSantosh Puranik  *
1564265c1602SJohnathan Mantey  * @return Integer error code.
1565491d8ee7SSantosh Puranik  */
1566cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1567cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1568491d8ee7SSantosh Puranik {
1569c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1570c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1571944ffaf9SJohnathan Mantey 
1572c21865c4SKonstantin Aladyshev     if (!bootSource)
1573491d8ee7SSantosh Puranik     {
1574c21865c4SKonstantin Aladyshev         return;
1575c21865c4SKonstantin Aladyshev     }
1576c21865c4SKonstantin Aladyshev 
1577491d8ee7SSantosh Puranik     // Source target specified
1578491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1579491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1580e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1581e662eae8SEd Tanous         0)
1582491d8ee7SSantosh Puranik     {
1583944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1584944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1585491d8ee7SSantosh Puranik             << *bootSource;
1586491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1587491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1588491d8ee7SSantosh Puranik         return;
1589491d8ee7SSantosh Puranik     }
1590491d8ee7SSantosh Puranik 
1591944ffaf9SJohnathan Mantey     // Act on validated parameters
1592944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1593944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1594944ffaf9SJohnathan Mantey 
1595491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1596491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1597491d8ee7SSantosh Puranik             if (ec)
1598491d8ee7SSantosh Puranik             {
1599491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1600491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1601491d8ee7SSantosh Puranik                 return;
1602491d8ee7SSantosh Puranik             }
1603491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source update done.";
1604491d8ee7SSantosh Puranik         },
1605c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1606c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1607491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1608491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1609168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1610944ffaf9SJohnathan Mantey 
1611491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1612491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1613491d8ee7SSantosh Puranik             if (ec)
1614491d8ee7SSantosh Puranik             {
1615491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1616491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1617491d8ee7SSantosh Puranik                 return;
1618491d8ee7SSantosh Puranik             }
1619491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode update done.";
1620491d8ee7SSantosh Puranik         },
1621c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1622c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1623491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1624491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1625168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1626cd9a4666SKonstantin Aladyshev }
1627944ffaf9SJohnathan Mantey 
1628cd9a4666SKonstantin Aladyshev /**
1629c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1630491d8ee7SSantosh Puranik  *
1631491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1632491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1633cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1634491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1635491d8ee7SSantosh Puranik  *
1636265c1602SJohnathan Mantey  * @return Integer error code.
1637491d8ee7SSantosh Puranik  */
1638c21865c4SKonstantin Aladyshev 
1639c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1640c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1641c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1642c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1643491d8ee7SSantosh Puranik {
1644491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1645491d8ee7SSantosh Puranik 
1646c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1647c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1648c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1649491d8ee7SSantosh Puranik }
1650491d8ee7SSantosh Puranik 
1651c6a620f2SGeorge Liu /**
165298e386ecSGunnar Mills  * @brief Sets AssetTag
165398e386ecSGunnar Mills  *
165498e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
165598e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
165698e386ecSGunnar Mills  *
165798e386ecSGunnar Mills  * @return None.
165898e386ecSGunnar Mills  */
16598d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
166098e386ecSGunnar Mills                         const std::string& assetTag)
166198e386ecSGunnar Mills {
166298e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
166398e386ecSGunnar Mills         [aResp, assetTag](
166498e386ecSGunnar Mills             const boost::system::error_code ec,
166598e386ecSGunnar Mills             const std::vector<std::pair<
166698e386ecSGunnar Mills                 std::string,
166798e386ecSGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
166898e386ecSGunnar Mills                 subtree) {
166998e386ecSGunnar Mills             if (ec)
167098e386ecSGunnar Mills             {
167198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
167298e386ecSGunnar Mills                 messages::internalError(aResp->res);
167398e386ecSGunnar Mills                 return;
167498e386ecSGunnar Mills             }
167526f6976fSEd Tanous             if (subtree.empty())
167698e386ecSGunnar Mills             {
167798e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
167898e386ecSGunnar Mills                 messages::internalError(aResp->res);
167998e386ecSGunnar Mills                 return;
168098e386ecSGunnar Mills             }
168198e386ecSGunnar Mills             // Assume only 1 system D-Bus object
168298e386ecSGunnar Mills             // Throw an error if there is more than 1
168398e386ecSGunnar Mills             if (subtree.size() > 1)
168498e386ecSGunnar Mills             {
168598e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
168698e386ecSGunnar Mills                 messages::internalError(aResp->res);
168798e386ecSGunnar Mills                 return;
168898e386ecSGunnar Mills             }
168998e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
169098e386ecSGunnar Mills             {
169198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
169298e386ecSGunnar Mills                 messages::internalError(aResp->res);
169398e386ecSGunnar Mills                 return;
169498e386ecSGunnar Mills             }
169598e386ecSGunnar Mills 
169698e386ecSGunnar Mills             const std::string& path = subtree[0].first;
169798e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
169898e386ecSGunnar Mills 
169998e386ecSGunnar Mills             if (service.empty())
170098e386ecSGunnar Mills             {
170198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
170298e386ecSGunnar Mills                 messages::internalError(aResp->res);
170398e386ecSGunnar Mills                 return;
170498e386ecSGunnar Mills             }
170598e386ecSGunnar Mills 
170698e386ecSGunnar Mills             crow::connections::systemBus->async_method_call(
170798e386ecSGunnar Mills                 [aResp](const boost::system::error_code ec2) {
170898e386ecSGunnar Mills                     if (ec2)
170998e386ecSGunnar Mills                     {
171098e386ecSGunnar Mills                         BMCWEB_LOG_DEBUG
171198e386ecSGunnar Mills                             << "D-Bus response error on AssetTag Set " << ec2;
171298e386ecSGunnar Mills                         messages::internalError(aResp->res);
171398e386ecSGunnar Mills                         return;
171498e386ecSGunnar Mills                     }
171598e386ecSGunnar Mills                 },
171698e386ecSGunnar Mills                 service, path, "org.freedesktop.DBus.Properties", "Set",
171798e386ecSGunnar Mills                 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1718168e20c1SEd Tanous                 dbus::utility::DbusVariantType(assetTag));
171998e386ecSGunnar Mills         },
172098e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
172198e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
172298e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
172398e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
172498e386ecSGunnar Mills         std::array<const char*, 1>{
172598e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
172698e386ecSGunnar Mills }
172798e386ecSGunnar Mills 
172898e386ecSGunnar Mills /**
172969f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
173069f35306SGunnar Mills  *
173169f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
173269f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
173369f35306SGunnar Mills  *
173469f35306SGunnar Mills  * @return None.
173569f35306SGunnar Mills  */
17368d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1737f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
173869f35306SGunnar Mills {
173969f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
174069f35306SGunnar Mills 
174169f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1742543f4400SEd Tanous     bool autoRebootEnabled = false;
174369f35306SGunnar Mills 
174469f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
174569f35306SGunnar Mills     {
174669f35306SGunnar Mills         autoRebootEnabled = false;
174769f35306SGunnar Mills     }
174869f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
174969f35306SGunnar Mills     {
175069f35306SGunnar Mills         autoRebootEnabled = true;
175169f35306SGunnar Mills     }
175269f35306SGunnar Mills     else
175369f35306SGunnar Mills     {
17540fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
175569f35306SGunnar Mills                          << automaticRetryConfig;
175669f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
175769f35306SGunnar Mills                                          "AutomaticRetryConfig");
175869f35306SGunnar Mills         return;
175969f35306SGunnar Mills     }
176069f35306SGunnar Mills 
176169f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
176269f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
176369f35306SGunnar Mills             if (ec)
176469f35306SGunnar Mills             {
176569f35306SGunnar Mills                 messages::internalError(aResp->res);
176669f35306SGunnar Mills                 return;
176769f35306SGunnar Mills             }
176869f35306SGunnar Mills         },
176969f35306SGunnar Mills         "xyz.openbmc_project.Settings",
177069f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
177169f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
177269f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1773168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
177469f35306SGunnar Mills }
177569f35306SGunnar Mills 
177669f35306SGunnar Mills /**
1777c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1778c6a620f2SGeorge Liu  *
1779c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1780c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1781c6a620f2SGeorge Liu  *
1782c6a620f2SGeorge Liu  * @return None.
1783c6a620f2SGeorge Liu  */
17848d1b46d7Szhanghch05 inline void
17858d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
17864e69c904SGunnar Mills                           const std::string& policy)
1787c6a620f2SGeorge Liu {
1788c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1789c6a620f2SGeorge Liu 
1790c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
17910fda0f12SGeorge Liu         {"AlwaysOn",
17920fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
17930fda0f12SGeorge Liu         {"AlwaysOff",
17940fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
17950fda0f12SGeorge Liu         {"LastState",
17960fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1797c6a620f2SGeorge Liu 
1798c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1799c6a620f2SGeorge Liu 
18004e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1801c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1802c6a620f2SGeorge Liu     {
18034e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
18044e69c904SGunnar Mills                                          "PowerRestorePolicy");
1805c6a620f2SGeorge Liu         return;
1806c6a620f2SGeorge Liu     }
1807c6a620f2SGeorge Liu 
1808c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1809c6a620f2SGeorge Liu 
1810c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1811c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1812c6a620f2SGeorge Liu             if (ec)
1813c6a620f2SGeorge Liu             {
1814c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1815c6a620f2SGeorge Liu                 return;
1816c6a620f2SGeorge Liu             }
1817c6a620f2SGeorge Liu         },
1818c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1819c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1820c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1821c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1822168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1823c6a620f2SGeorge Liu }
1824c6a620f2SGeorge Liu 
1825a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1826a6349918SAppaRao Puli /**
1827a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1828a6349918SAppaRao Puli  *
1829a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1830a6349918SAppaRao Puli  *
1831a6349918SAppaRao Puli  * @return None.
1832a6349918SAppaRao Puli  */
18338d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1834a6349918SAppaRao Puli {
1835a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1836a6349918SAppaRao Puli     crow::connections::systemBus->async_method_call(
1837a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
18386e3b67ecSAppaRao Puli                 const std::vector<
18396e3b67ecSAppaRao Puli                     std::pair<std::string, dbus::utility::DbusVariantType>>&
18401214b7e7SGunnar Mills                     propertiesList) {
1841b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1842b99fb1a9SAppaRao Puli                 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
184350626f4fSJames Feist             aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
184450626f4fSJames Feist                 "#OemComputerSystem.OpenBmc";
184550626f4fSJames Feist             oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
184650626f4fSJames Feist 
1847a6349918SAppaRao Puli             if (ec)
1848a6349918SAppaRao Puli             {
1849a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1850b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1851b99fb1a9SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1852a6349918SAppaRao Puli                 return;
1853a6349918SAppaRao Puli             }
1854a6349918SAppaRao Puli 
1855a6349918SAppaRao Puli             const bool* provState = nullptr;
1856a6349918SAppaRao Puli             const bool* lockState = nullptr;
18576e3b67ecSAppaRao Puli             for (const std::pair<std::string, dbus::utility::DbusVariantType>&
18586e3b67ecSAppaRao Puli                      property : propertiesList)
1859a6349918SAppaRao Puli             {
1860a6349918SAppaRao Puli                 if (property.first == "UfmProvisioned")
1861a6349918SAppaRao Puli                 {
1862a6349918SAppaRao Puli                     provState = std::get_if<bool>(&property.second);
1863a6349918SAppaRao Puli                 }
1864a6349918SAppaRao Puli                 else if (property.first == "UfmLocked")
1865a6349918SAppaRao Puli                 {
1866a6349918SAppaRao Puli                     lockState = std::get_if<bool>(&property.second);
1867a6349918SAppaRao Puli                 }
1868a6349918SAppaRao Puli             }
1869a6349918SAppaRao Puli 
1870a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
1871a6349918SAppaRao Puli             {
1872a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1873a6349918SAppaRao Puli                 messages::internalError(aResp->res);
1874a6349918SAppaRao Puli                 return;
1875a6349918SAppaRao Puli             }
1876a6349918SAppaRao Puli 
1877a6349918SAppaRao Puli             if (*provState == true)
1878a6349918SAppaRao Puli             {
1879a6349918SAppaRao Puli                 if (*lockState == true)
1880a6349918SAppaRao Puli                 {
1881a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1882a6349918SAppaRao Puli                 }
1883a6349918SAppaRao Puli                 else
1884a6349918SAppaRao Puli                 {
1885a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1886a6349918SAppaRao Puli                 }
1887a6349918SAppaRao Puli             }
1888a6349918SAppaRao Puli             else
1889a6349918SAppaRao Puli             {
1890a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1891a6349918SAppaRao Puli             }
1892a6349918SAppaRao Puli         },
1893a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1894a6349918SAppaRao Puli         "org.freedesktop.DBus.Properties", "GetAll",
1895a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Attributes");
1896a6349918SAppaRao Puli }
1897a6349918SAppaRao Puli #endif
1898a6349918SAppaRao Puli 
1899491d8ee7SSantosh Puranik /**
19003a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
19013a2d0424SChris Cain  *
19023a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19033a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
19043a2d0424SChris Cain  *
19053a2d0424SChris Cain  * @return None.
19063a2d0424SChris Cain  */
19073a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19083a2d0424SChris Cain                                const std::string& modeValue)
19093a2d0424SChris Cain {
19103a2d0424SChris Cain     std::string modeString;
19113a2d0424SChris Cain 
19120fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
19133a2d0424SChris Cain     {
19143a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
19153a2d0424SChris Cain     }
19160fda0f12SGeorge Liu     else if (
19170fda0f12SGeorge Liu         modeValue ==
19180fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
19193a2d0424SChris Cain     {
19203a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
19213a2d0424SChris Cain     }
19220fda0f12SGeorge Liu     else if (modeValue ==
19230fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
19243a2d0424SChris Cain     {
19253a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
19263a2d0424SChris Cain     }
19270fda0f12SGeorge Liu     else if (modeValue ==
19280fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
19293a2d0424SChris Cain     {
19303a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
19313a2d0424SChris Cain     }
19323a2d0424SChris Cain     else
19333a2d0424SChris Cain     {
19343a2d0424SChris Cain         // Any other values would be invalid
19353a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
19363a2d0424SChris Cain         messages::internalError(aResp->res);
19373a2d0424SChris Cain     }
19383a2d0424SChris Cain }
19393a2d0424SChris Cain 
19403a2d0424SChris Cain /**
19413a2d0424SChris Cain  * @brief Retrieves system power mode
19423a2d0424SChris Cain  *
19433a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19443a2d0424SChris Cain  *
19453a2d0424SChris Cain  * @return None.
19463a2d0424SChris Cain  */
19473a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
19483a2d0424SChris Cain {
19493a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
19503a2d0424SChris Cain 
19513a2d0424SChris Cain     // Get Power Mode object path:
19523a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
19533a2d0424SChris Cain         [aResp](
19543a2d0424SChris Cain             const boost::system::error_code ec,
19553a2d0424SChris Cain             const std::vector<std::pair<
19563a2d0424SChris Cain                 std::string,
19573a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
19583a2d0424SChris Cain                 subtree) {
19593a2d0424SChris Cain             if (ec)
19603a2d0424SChris Cain             {
19613a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
19623a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
19633a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
19643a2d0424SChris Cain                 // error occurs
19653a2d0424SChris Cain                 return;
19663a2d0424SChris Cain             }
19673a2d0424SChris Cain             if (subtree.empty())
19683a2d0424SChris Cain             {
19693a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
19703a2d0424SChris Cain                 // if there is no instance found
19713a2d0424SChris Cain                 return;
19723a2d0424SChris Cain             }
19733a2d0424SChris Cain             if (subtree.size() > 1)
19743a2d0424SChris Cain             {
19753a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
19763a2d0424SChris Cain                 // error
19773a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
19783a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
19793a2d0424SChris Cain                     << subtree.size();
19803a2d0424SChris Cain                 messages::internalError(aResp->res);
19813a2d0424SChris Cain                 return;
19823a2d0424SChris Cain             }
19833a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
19843a2d0424SChris Cain             {
19853a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
19863a2d0424SChris Cain                 messages::internalError(aResp->res);
19873a2d0424SChris Cain                 return;
19883a2d0424SChris Cain             }
19893a2d0424SChris Cain             const std::string& path = subtree[0].first;
19903a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
19913a2d0424SChris Cain             if (service.empty())
19923a2d0424SChris Cain             {
19933a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
19943a2d0424SChris Cain                 messages::internalError(aResp->res);
19953a2d0424SChris Cain                 return;
19963a2d0424SChris Cain             }
19973a2d0424SChris Cain             // Valid Power Mode object found, now read the current value
19981e1e598dSJonathan Doman             sdbusplus::asio::getProperty<std::string>(
19991e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
20001e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
20013a2d0424SChris Cain                 [aResp](const boost::system::error_code ec,
20021e1e598dSJonathan Doman                         const std::string& pmode) {
20033a2d0424SChris Cain                     if (ec)
20043a2d0424SChris Cain                     {
20053a2d0424SChris Cain                         BMCWEB_LOG_DEBUG
20063a2d0424SChris Cain                             << "DBUS response error on PowerMode Get: " << ec;
20073a2d0424SChris Cain                         messages::internalError(aResp->res);
20083a2d0424SChris Cain                         return;
20093a2d0424SChris Cain                     }
20103a2d0424SChris Cain 
20113a2d0424SChris Cain                     aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] =
20123a2d0424SChris Cain                         {"Static", "MaximumPerformance", "PowerSaving"};
20133a2d0424SChris Cain 
20141e1e598dSJonathan Doman                     BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
20151e1e598dSJonathan Doman                     translatePowerMode(aResp, pmode);
20161e1e598dSJonathan Doman                 });
20173a2d0424SChris Cain         },
20183a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
20193a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
20203a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
20213a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
20223a2d0424SChris Cain }
20233a2d0424SChris Cain 
20243a2d0424SChris Cain /**
20253a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
20263a2d0424SChris Cain  * name associated with that string
20273a2d0424SChris Cain  *
20283a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20293a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
20303a2d0424SChris Cain  *
20313a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
20323a2d0424SChris Cain  */
20333a2d0424SChris Cain inline std::string
20343a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20353a2d0424SChris Cain                       const std::string& modeString)
20363a2d0424SChris Cain {
20373a2d0424SChris Cain     std::string mode;
20383a2d0424SChris Cain 
20393a2d0424SChris Cain     if (modeString == "Static")
20403a2d0424SChris Cain     {
20413a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
20423a2d0424SChris Cain     }
20433a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
20443a2d0424SChris Cain     {
20450fda0f12SGeorge Liu         mode =
20460fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
20473a2d0424SChris Cain     }
20483a2d0424SChris Cain     else if (modeString == "PowerSaving")
20493a2d0424SChris Cain     {
20503a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
20513a2d0424SChris Cain     }
20523a2d0424SChris Cain     else
20533a2d0424SChris Cain     {
20543a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
20553a2d0424SChris Cain     }
20563a2d0424SChris Cain     return mode;
20573a2d0424SChris Cain }
20583a2d0424SChris Cain 
20593a2d0424SChris Cain /**
20603a2d0424SChris Cain  * @brief Sets system power mode.
20613a2d0424SChris Cain  *
20623a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20633a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
20643a2d0424SChris Cain  *
20653a2d0424SChris Cain  * @return None.
20663a2d0424SChris Cain  */
20673a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20683a2d0424SChris Cain                          const std::string& pmode)
20693a2d0424SChris Cain {
20703a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
20713a2d0424SChris Cain 
20723a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
20733a2d0424SChris Cain     if (powerMode.empty())
20743a2d0424SChris Cain     {
20753a2d0424SChris Cain         return;
20763a2d0424SChris Cain     }
20773a2d0424SChris Cain 
20783a2d0424SChris Cain     // Get Power Mode object path:
20793a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
20803a2d0424SChris Cain         [aResp, powerMode](
20813a2d0424SChris Cain             const boost::system::error_code ec,
20823a2d0424SChris Cain             const std::vector<std::pair<
20833a2d0424SChris Cain                 std::string,
20843a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
20853a2d0424SChris Cain                 subtree) {
20863a2d0424SChris Cain             if (ec)
20873a2d0424SChris Cain             {
20883a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20893a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
20903a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
20913a2d0424SChris Cain                 messages::internalError(aResp->res);
20923a2d0424SChris Cain                 return;
20933a2d0424SChris Cain             }
20943a2d0424SChris Cain             if (subtree.empty())
20953a2d0424SChris Cain             {
20963a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
20973a2d0424SChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
20983a2d0424SChris Cain                                            "PowerMode");
20993a2d0424SChris Cain                 return;
21003a2d0424SChris Cain             }
21013a2d0424SChris Cain             if (subtree.size() > 1)
21023a2d0424SChris Cain             {
21033a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
21043a2d0424SChris Cain                 // error
21053a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
21063a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
21073a2d0424SChris Cain                     << subtree.size();
21083a2d0424SChris Cain                 messages::internalError(aResp->res);
21093a2d0424SChris Cain                 return;
21103a2d0424SChris Cain             }
21113a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21123a2d0424SChris Cain             {
21133a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21143a2d0424SChris Cain                 messages::internalError(aResp->res);
21153a2d0424SChris Cain                 return;
21163a2d0424SChris Cain             }
21173a2d0424SChris Cain             const std::string& path = subtree[0].first;
21183a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21193a2d0424SChris Cain             if (service.empty())
21203a2d0424SChris Cain             {
21213a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21223a2d0424SChris Cain                 messages::internalError(aResp->res);
21233a2d0424SChris Cain                 return;
21243a2d0424SChris Cain             }
21253a2d0424SChris Cain 
21263a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
21273a2d0424SChris Cain                              << path;
21283a2d0424SChris Cain 
21293a2d0424SChris Cain             // Set the Power Mode property
21303a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
21313a2d0424SChris Cain                 [aResp](const boost::system::error_code ec) {
21323a2d0424SChris Cain                     if (ec)
21333a2d0424SChris Cain                     {
21343a2d0424SChris Cain                         messages::internalError(aResp->res);
21353a2d0424SChris Cain                         return;
21363a2d0424SChris Cain                     }
21373a2d0424SChris Cain                 },
21383a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
21393a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2140168e20c1SEd Tanous                 dbus::utility::DbusVariantType(powerMode));
21413a2d0424SChris Cain         },
21423a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
21433a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
21443a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
21453a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
21463a2d0424SChris Cain }
21473a2d0424SChris Cain 
21483a2d0424SChris Cain /**
214951709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
215051709ffdSYong Li  *
215151709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
215251709ffdSYong Li  *
215351709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
215451709ffdSYong Li  * translation cannot be done, returns an empty string.
215551709ffdSYong Li  */
215623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
215751709ffdSYong Li {
215851709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
215951709ffdSYong Li     {
216051709ffdSYong Li         return "None";
216151709ffdSYong Li     }
21623174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
216351709ffdSYong Li     {
216451709ffdSYong Li         return "ResetSystem";
216551709ffdSYong Li     }
21663174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
216751709ffdSYong Li     {
216851709ffdSYong Li         return "PowerDown";
216951709ffdSYong Li     }
21703174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
217151709ffdSYong Li     {
217251709ffdSYong Li         return "PowerCycle";
217351709ffdSYong Li     }
217451709ffdSYong Li 
217551709ffdSYong Li     return "";
217651709ffdSYong Li }
217751709ffdSYong Li 
217851709ffdSYong Li /**
2179c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2180c45f0082SYong Li  *
2181c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2182c45f0082SYong Li  *
2183c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2184c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2185c45f0082SYong Li  */
2186c45f0082SYong Li 
218723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2188c45f0082SYong Li {
2189c45f0082SYong Li     if (rfAction == "None")
2190c45f0082SYong Li     {
2191c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2192c45f0082SYong Li     }
21933174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2194c45f0082SYong Li     {
2195c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2196c45f0082SYong Li     }
21973174e4dfSEd Tanous     if (rfAction == "PowerDown")
2198c45f0082SYong Li     {
2199c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2200c45f0082SYong Li     }
22013174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2202c45f0082SYong Li     {
2203c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2204c45f0082SYong Li     }
2205c45f0082SYong Li 
2206c45f0082SYong Li     return "";
2207c45f0082SYong Li }
2208c45f0082SYong Li 
2209c45f0082SYong Li /**
221051709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
221151709ffdSYong Li  *
221251709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
221351709ffdSYong Li  *
221451709ffdSYong Li  * @return None.
221551709ffdSYong Li  */
22168d1b46d7Szhanghch05 inline void
22178d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
221851709ffdSYong Li {
221951709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
222051709ffdSYong Li     crow::connections::systemBus->async_method_call(
222151709ffdSYong Li         [aResp](const boost::system::error_code ec,
2222914e2d5dSEd Tanous                 const PropertiesType& properties) {
222351709ffdSYong Li             if (ec)
222451709ffdSYong Li             {
222551709ffdSYong Li                 // watchdog service is stopped
222651709ffdSYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
222751709ffdSYong Li                 return;
222851709ffdSYong Li             }
222951709ffdSYong Li 
223051709ffdSYong Li             BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
223151709ffdSYong Li 
223251709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
223351709ffdSYong Li                 aResp->res.jsonValue["HostWatchdogTimer"];
223451709ffdSYong Li 
223551709ffdSYong Li             // watchdog service is running/enabled
223651709ffdSYong Li             hostWatchdogTimer["Status"]["State"] = "Enabled";
223751709ffdSYong Li 
223851709ffdSYong Li             for (const auto& property : properties)
223951709ffdSYong Li             {
224051709ffdSYong Li                 BMCWEB_LOG_DEBUG << "prop=" << property.first;
224151709ffdSYong Li                 if (property.first == "Enabled")
224251709ffdSYong Li                 {
224351709ffdSYong Li                     const bool* state = std::get_if<bool>(&property.second);
224451709ffdSYong Li 
2245e662eae8SEd Tanous                     if (state == nullptr)
224651709ffdSYong Li                     {
224751709ffdSYong Li                         messages::internalError(aResp->res);
2248601af5edSChicago Duan                         return;
224951709ffdSYong Li                     }
225051709ffdSYong Li 
225151709ffdSYong Li                     hostWatchdogTimer["FunctionEnabled"] = *state;
225251709ffdSYong Li                 }
225351709ffdSYong Li                 else if (property.first == "ExpireAction")
225451709ffdSYong Li                 {
225551709ffdSYong Li                     const std::string* s =
225651709ffdSYong Li                         std::get_if<std::string>(&property.second);
2257e662eae8SEd Tanous                     if (s == nullptr)
225851709ffdSYong Li                     {
225951709ffdSYong Li                         messages::internalError(aResp->res);
2260601af5edSChicago Duan                         return;
226151709ffdSYong Li                     }
226251709ffdSYong Li 
226351709ffdSYong Li                     std::string action = dbusToRfWatchdogAction(*s);
226451709ffdSYong Li                     if (action.empty())
226551709ffdSYong Li                     {
226651709ffdSYong Li                         messages::internalError(aResp->res);
2267601af5edSChicago Duan                         return;
226851709ffdSYong Li                     }
226951709ffdSYong Li                     hostWatchdogTimer["TimeoutAction"] = action;
227051709ffdSYong Li                 }
227151709ffdSYong Li             }
227251709ffdSYong Li         },
227351709ffdSYong Li         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
227451709ffdSYong Li         "org.freedesktop.DBus.Properties", "GetAll",
227551709ffdSYong Li         "xyz.openbmc_project.State.Watchdog");
227651709ffdSYong Li }
227751709ffdSYong Li 
227851709ffdSYong Li /**
2279c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2280c45f0082SYong Li  *
2281c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2282c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2283c45f0082SYong Li  *                       RF request.
2284c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2285c45f0082SYong Li  *
2286c45f0082SYong Li  * @return None.
2287c45f0082SYong Li  */
22888d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2289c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2290c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2291c45f0082SYong Li {
2292c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2293c45f0082SYong Li 
2294c45f0082SYong Li     if (wdtTimeOutAction)
2295c45f0082SYong Li     {
2296c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2297c45f0082SYong Li         // check if TimeOut Action is Valid
2298c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2299c45f0082SYong Li         {
2300c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2301c45f0082SYong Li                              << *wdtTimeOutAction;
2302c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2303c45f0082SYong Li                                              "TimeoutAction");
2304c45f0082SYong Li             return;
2305c45f0082SYong Li         }
2306c45f0082SYong Li 
2307c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2308c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2309c45f0082SYong Li                 if (ec)
2310c45f0082SYong Li                 {
2311c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2312c45f0082SYong Li                     messages::internalError(aResp->res);
2313c45f0082SYong Li                     return;
2314c45f0082SYong Li                 }
2315c45f0082SYong Li             },
2316c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2317c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2318c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2319c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2320168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2321c45f0082SYong Li     }
2322c45f0082SYong Li 
2323c45f0082SYong Li     if (wdtEnable)
2324c45f0082SYong Li     {
2325c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2326c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2327c45f0082SYong Li                 if (ec)
2328c45f0082SYong Li                 {
2329c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2330c45f0082SYong Li                     messages::internalError(aResp->res);
2331c45f0082SYong Li                     return;
2332c45f0082SYong Li                 }
2333c45f0082SYong Li             },
2334c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2335c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2336c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2337c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2338168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2339c45f0082SYong Li     }
2340c45f0082SYong Li }
2341c45f0082SYong Li 
234237bbf98cSChris Cain using ipsPropertiesType =
234337bbf98cSChris Cain     std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>;
234437bbf98cSChris Cain /**
234537bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
234637bbf98cSChris Cain  *
234737bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
234837bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
234937bbf98cSChris Cain  *
235037bbf98cSChris Cain  * @return true if successful
235137bbf98cSChris Cain  */
2352f6674220SEd Tanous inline bool parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
235337bbf98cSChris Cain                                ipsPropertiesType& properties)
235437bbf98cSChris Cain {
235537bbf98cSChris Cain     for (const auto& property : properties)
235637bbf98cSChris Cain     {
235737bbf98cSChris Cain         if (property.first == "Enabled")
235837bbf98cSChris Cain         {
235937bbf98cSChris Cain             const bool* state = std::get_if<bool>(&property.second);
2360e662eae8SEd Tanous             if (state == nullptr)
236137bbf98cSChris Cain             {
236237bbf98cSChris Cain                 return false;
236337bbf98cSChris Cain             }
236437bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *state;
236537bbf98cSChris Cain         }
236637bbf98cSChris Cain         else if (property.first == "EnterUtilizationPercent")
236737bbf98cSChris Cain         {
236837bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
2369e662eae8SEd Tanous             if (util == nullptr)
237037bbf98cSChris Cain             {
237137bbf98cSChris Cain                 return false;
237237bbf98cSChris Cain             }
237337bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
237437bbf98cSChris Cain         }
237537bbf98cSChris Cain         else if (property.first == "EnterDwellTime")
237637bbf98cSChris Cain         {
237737bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
237837bbf98cSChris Cain             const uint64_t* timeMilliseconds =
237937bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
2380e662eae8SEd Tanous             if (timeMilliseconds == nullptr)
238137bbf98cSChris Cain             {
238237bbf98cSChris Cain                 return false;
238337bbf98cSChris Cain             }
238437bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
238537bbf98cSChris Cain                 *timeMilliseconds);
238637bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
238737bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
238837bbf98cSChris Cain                     .count();
238937bbf98cSChris Cain         }
239037bbf98cSChris Cain         else if (property.first == "ExitUtilizationPercent")
239137bbf98cSChris Cain         {
239237bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
2393e662eae8SEd Tanous             if (util == nullptr)
239437bbf98cSChris Cain             {
239537bbf98cSChris Cain                 return false;
239637bbf98cSChris Cain             }
239737bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
239837bbf98cSChris Cain         }
239937bbf98cSChris Cain         else if (property.first == "ExitDwellTime")
240037bbf98cSChris Cain         {
240137bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
240237bbf98cSChris Cain             const uint64_t* timeMilliseconds =
240337bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
2404e662eae8SEd Tanous             if (timeMilliseconds == nullptr)
240537bbf98cSChris Cain             {
240637bbf98cSChris Cain                 return false;
240737bbf98cSChris Cain             }
240837bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
240937bbf98cSChris Cain                 *timeMilliseconds);
241037bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
241137bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
241237bbf98cSChris Cain                     .count();
241337bbf98cSChris Cain         }
241437bbf98cSChris Cain         else
241537bbf98cSChris Cain         {
241637bbf98cSChris Cain             BMCWEB_LOG_WARNING << "Unexpected IdlePowerSaver property: "
241737bbf98cSChris Cain                                << property.first;
241837bbf98cSChris Cain         }
241937bbf98cSChris Cain     }
242037bbf98cSChris Cain 
242137bbf98cSChris Cain     return true;
242237bbf98cSChris Cain }
242337bbf98cSChris Cain 
242437bbf98cSChris Cain /**
242537bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
242637bbf98cSChris Cain  *
242737bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
242837bbf98cSChris Cain  *
242937bbf98cSChris Cain  * @return None.
243037bbf98cSChris Cain  */
243137bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
243237bbf98cSChris Cain {
243337bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
243437bbf98cSChris Cain 
243537bbf98cSChris Cain     // Get IdlePowerSaver object path:
243637bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
243737bbf98cSChris Cain         [aResp](
243837bbf98cSChris Cain             const boost::system::error_code ec,
243937bbf98cSChris Cain             const std::vector<std::pair<
244037bbf98cSChris Cain                 std::string,
244137bbf98cSChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
244237bbf98cSChris Cain                 subtree) {
244337bbf98cSChris Cain             if (ec)
244437bbf98cSChris Cain             {
244537bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
244637bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
244737bbf98cSChris Cain                     << ec;
244837bbf98cSChris Cain                 messages::internalError(aResp->res);
244937bbf98cSChris Cain                 return;
245037bbf98cSChris Cain             }
245137bbf98cSChris Cain             if (subtree.empty())
245237bbf98cSChris Cain             {
245337bbf98cSChris Cain                 // This is an optional interface so just return
245437bbf98cSChris Cain                 // if there is no instance found
245537bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "No instances found";
245637bbf98cSChris Cain                 return;
245737bbf98cSChris Cain             }
245837bbf98cSChris Cain             if (subtree.size() > 1)
245937bbf98cSChris Cain             {
246037bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
246137bbf98cSChris Cain                 // is an error
246237bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
246337bbf98cSChris Cain                                     "Power.IdlePowerSaver objects: "
246437bbf98cSChris Cain                                  << subtree.size();
246537bbf98cSChris Cain                 messages::internalError(aResp->res);
246637bbf98cSChris Cain                 return;
246737bbf98cSChris Cain             }
246837bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
246937bbf98cSChris Cain             {
247037bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
247137bbf98cSChris Cain                 messages::internalError(aResp->res);
247237bbf98cSChris Cain                 return;
247337bbf98cSChris Cain             }
247437bbf98cSChris Cain             const std::string& path = subtree[0].first;
247537bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
247637bbf98cSChris Cain             if (service.empty())
247737bbf98cSChris Cain             {
247837bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
247937bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
248037bbf98cSChris Cain                 messages::internalError(aResp->res);
248137bbf98cSChris Cain                 return;
248237bbf98cSChris Cain             }
248337bbf98cSChris Cain 
248437bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
248537bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
248637bbf98cSChris Cain                 [aResp](const boost::system::error_code ec,
248737bbf98cSChris Cain                         ipsPropertiesType& properties) {
248837bbf98cSChris Cain                     if (ec)
248937bbf98cSChris Cain                     {
249037bbf98cSChris Cain                         BMCWEB_LOG_ERROR
249137bbf98cSChris Cain                             << "DBUS response error on IdlePowerSaver GetAll: "
249237bbf98cSChris Cain                             << ec;
249337bbf98cSChris Cain                         messages::internalError(aResp->res);
249437bbf98cSChris Cain                         return;
249537bbf98cSChris Cain                     }
249637bbf98cSChris Cain 
2497e05aec50SEd Tanous                     if (!parseIpsProperties(aResp, properties))
249837bbf98cSChris Cain                     {
249937bbf98cSChris Cain                         messages::internalError(aResp->res);
250037bbf98cSChris Cain                         return;
250137bbf98cSChris Cain                     }
250237bbf98cSChris Cain                 },
250337bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "GetAll",
250437bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver");
250537bbf98cSChris Cain         },
250637bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
250737bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
250837bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
250937bbf98cSChris Cain         std::array<const char*, 1>{
251037bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
251137bbf98cSChris Cain 
251237bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
251337bbf98cSChris Cain }
251437bbf98cSChris Cain 
251537bbf98cSChris Cain /**
251637bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
251737bbf98cSChris Cain  *
251837bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
251937bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
252037bbf98cSChris Cain  *                       RF request.
252137bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
252237bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
252337bbf98cSChris Cain  * before entering idle state.
252437bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
252537bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
252637bbf98cSChris Cain  * before exiting idle state
252737bbf98cSChris Cain  *
252837bbf98cSChris Cain  * @return None.
252937bbf98cSChris Cain  */
253037bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
253137bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
253237bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
253337bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
253437bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
253537bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
253637bbf98cSChris Cain {
253737bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
253837bbf98cSChris Cain 
253937bbf98cSChris Cain     // Get IdlePowerSaver object path:
254037bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
254137bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
254237bbf98cSChris Cain          ipsExitTime](
254337bbf98cSChris Cain             const boost::system::error_code ec,
254437bbf98cSChris Cain             const std::vector<std::pair<
254537bbf98cSChris Cain                 std::string,
254637bbf98cSChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
254737bbf98cSChris Cain                 subtree) {
254837bbf98cSChris Cain             if (ec)
254937bbf98cSChris Cain             {
255037bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
255137bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
255237bbf98cSChris Cain                     << ec;
255337bbf98cSChris Cain                 messages::internalError(aResp->res);
255437bbf98cSChris Cain                 return;
255537bbf98cSChris Cain             }
255637bbf98cSChris Cain             if (subtree.empty())
255737bbf98cSChris Cain             {
255837bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
255937bbf98cSChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
256037bbf98cSChris Cain                                            "IdlePowerSaver");
256137bbf98cSChris Cain                 return;
256237bbf98cSChris Cain             }
256337bbf98cSChris Cain             if (subtree.size() > 1)
256437bbf98cSChris Cain             {
256537bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
256637bbf98cSChris Cain                 // is an error
25670fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
25680fda0f12SGeorge Liu                     << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
256937bbf98cSChris Cain                     << subtree.size();
257037bbf98cSChris Cain                 messages::internalError(aResp->res);
257137bbf98cSChris Cain                 return;
257237bbf98cSChris Cain             }
257337bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
257437bbf98cSChris Cain             {
257537bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
257637bbf98cSChris Cain                 messages::internalError(aResp->res);
257737bbf98cSChris Cain                 return;
257837bbf98cSChris Cain             }
257937bbf98cSChris Cain             const std::string& path = subtree[0].first;
258037bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
258137bbf98cSChris Cain             if (service.empty())
258237bbf98cSChris Cain             {
258337bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
258437bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
258537bbf98cSChris Cain                 messages::internalError(aResp->res);
258637bbf98cSChris Cain                 return;
258737bbf98cSChris Cain             }
258837bbf98cSChris Cain 
258937bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
259037bbf98cSChris Cain             // need to be updated
259137bbf98cSChris Cain 
259237bbf98cSChris Cain             if (ipsEnable)
259337bbf98cSChris Cain             {
259437bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
259537bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
259637bbf98cSChris Cain                         if (ec)
259737bbf98cSChris Cain                         {
259837bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
259937bbf98cSChris Cain                             messages::internalError(aResp->res);
260037bbf98cSChris Cain                             return;
260137bbf98cSChris Cain                         }
260237bbf98cSChris Cain                     },
260337bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
260437bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2605168e20c1SEd Tanous                     "Enabled", dbus::utility::DbusVariantType(*ipsEnable));
260637bbf98cSChris Cain             }
260737bbf98cSChris Cain             if (ipsEnterUtil)
260837bbf98cSChris Cain             {
260937bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
261037bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
261137bbf98cSChris Cain                         if (ec)
261237bbf98cSChris Cain                         {
261337bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
261437bbf98cSChris Cain                             messages::internalError(aResp->res);
261537bbf98cSChris Cain                             return;
261637bbf98cSChris Cain                         }
261737bbf98cSChris Cain                     },
261837bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
261937bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
262037bbf98cSChris Cain                     "EnterUtilizationPercent",
2621168e20c1SEd Tanous                     dbus::utility::DbusVariantType(*ipsEnterUtil));
262237bbf98cSChris Cain             }
262337bbf98cSChris Cain             if (ipsEnterTime)
262437bbf98cSChris Cain             {
262537bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
262637bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
262737bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
262837bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
262937bbf98cSChris Cain                         if (ec)
263037bbf98cSChris Cain                         {
263137bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
263237bbf98cSChris Cain                             messages::internalError(aResp->res);
263337bbf98cSChris Cain                             return;
263437bbf98cSChris Cain                         }
263537bbf98cSChris Cain                     },
263637bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
263737bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2638168e20c1SEd Tanous                     "EnterDwellTime",
2639168e20c1SEd Tanous                     dbus::utility::DbusVariantType(timeMilliseconds));
264037bbf98cSChris Cain             }
264137bbf98cSChris Cain             if (ipsExitUtil)
264237bbf98cSChris Cain             {
264337bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
264437bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
264537bbf98cSChris Cain                         if (ec)
264637bbf98cSChris Cain                         {
264737bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
264837bbf98cSChris Cain                             messages::internalError(aResp->res);
264937bbf98cSChris Cain                             return;
265037bbf98cSChris Cain                         }
265137bbf98cSChris Cain                     },
265237bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
265337bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
265437bbf98cSChris Cain                     "ExitUtilizationPercent",
2655168e20c1SEd Tanous                     dbus::utility::DbusVariantType(*ipsExitUtil));
265637bbf98cSChris Cain             }
265737bbf98cSChris Cain             if (ipsExitTime)
265837bbf98cSChris Cain             {
265937bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
266037bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
266137bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
266237bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
266337bbf98cSChris Cain                         if (ec)
266437bbf98cSChris Cain                         {
266537bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
266637bbf98cSChris Cain                             messages::internalError(aResp->res);
266737bbf98cSChris Cain                             return;
266837bbf98cSChris Cain                         }
266937bbf98cSChris Cain                     },
267037bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
267137bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2672168e20c1SEd Tanous                     "ExitDwellTime",
2673168e20c1SEd Tanous                     dbus::utility::DbusVariantType(timeMilliseconds));
267437bbf98cSChris Cain             }
267537bbf98cSChris Cain         },
267637bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
267737bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
267837bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
267937bbf98cSChris Cain         std::array<const char*, 1>{
268037bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
268137bbf98cSChris Cain 
268237bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
268337bbf98cSChris Cain }
268437bbf98cSChris Cain 
2685c45f0082SYong Li /**
2686c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2687c5b2abe0SLewanczyk, Dawid  * Schema
2688c5b2abe0SLewanczyk, Dawid  */
26897e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
26901abe55efSEd Tanous {
26917e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2692ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
26937e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
26944f48d5f6SEd Tanous             [](const crow::Request& /*req*/,
26957e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
26968d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
26970f74e643SEd Tanous                     "#ComputerSystemCollection.ComputerSystemCollection";
26988d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
26998d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2700462023adSSunitha Harish 
27011e1e598dSJonathan Doman                 sdbusplus::asio::getProperty<std::string>(
27021e1e598dSJonathan Doman                     *crow::connections::systemBus,
27031e1e598dSJonathan Doman                     "xyz.openbmc_project.Settings",
27041e1e598dSJonathan Doman                     "/xyz/openbmc_project/network/hypervisor",
27051e1e598dSJonathan Doman                     "xyz.openbmc_project.Network.SystemConfiguration",
27061e1e598dSJonathan Doman                     "HostName",
27071e1e598dSJonathan Doman                     [asyncResp](const boost::system::error_code ec,
27081e1e598dSJonathan Doman                                 const std::string& /*hostName*/) {
27092c70f800SEd Tanous                         nlohmann::json& ifaceArray =
2710462023adSSunitha Harish                             asyncResp->res.jsonValue["Members"];
27112c70f800SEd Tanous                         ifaceArray = nlohmann::json::array();
27127e860f15SJohn Edward Broadbent                         auto& count =
27137e860f15SJohn Edward Broadbent                             asyncResp->res.jsonValue["Members@odata.count"];
27142c70f800SEd Tanous                         ifaceArray.push_back(
2715cb13a392SEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/system"}});
271694bda602STim Lee                         count = ifaceArray.size();
2717cb13a392SEd Tanous                         if (!ec)
2718462023adSSunitha Harish                         {
2719462023adSSunitha Harish                             BMCWEB_LOG_DEBUG << "Hypervisor is available";
27202c70f800SEd Tanous                             ifaceArray.push_back(
27217e860f15SJohn Edward Broadbent                                 {{"@odata.id",
27227e860f15SJohn Edward Broadbent                                   "/redfish/v1/Systems/hypervisor"}});
27232c70f800SEd Tanous                             count = ifaceArray.size();
2724cb13a392SEd Tanous                         }
27251e1e598dSJonathan Doman                     });
27267e860f15SJohn Edward Broadbent             });
2727c5b2abe0SLewanczyk, Dawid }
27287e860f15SJohn Edward Broadbent 
27297e860f15SJohn Edward Broadbent /**
27307e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
27317e860f15SJohn Edward Broadbent  */
27324f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27337e860f15SJohn Edward Broadbent {
27347e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
27357e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
27367e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
27377e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
27387e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
27397e860f15SJohn Edward Broadbent 
27407e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
27417e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
27427e860f15SJohn Edward Broadbent             if (ec)
27437e860f15SJohn Edward Broadbent             {
27447e860f15SJohn Edward Broadbent                 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
27457e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
27467e860f15SJohn Edward Broadbent                 return;
27477e860f15SJohn Edward Broadbent             }
27487e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
27497e860f15SJohn Edward Broadbent         },
27507e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
27517e860f15SJohn Edward Broadbent }
2752c5b2abe0SLewanczyk, Dawid 
2753c5b2abe0SLewanczyk, Dawid /**
2754cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2755cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2756cc340dd9SEd Tanous  */
27577e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2758cc340dd9SEd Tanous {
2759cc340dd9SEd Tanous     /**
2760cc340dd9SEd Tanous      * Function handles POST method request.
2761cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2762cc340dd9SEd Tanous      */
27637e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
27647e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2765ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
27667e860f15SJohn Edward Broadbent         .methods(
27677e860f15SJohn Edward Broadbent             boost::beast::http::verb::
27687e860f15SJohn Edward Broadbent                 post)([](const crow::Request& req,
27697e860f15SJohn Edward Broadbent                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27709712f8acSEd Tanous             std::string resetType;
277115ed6780SWilly Tu             if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
27727e860f15SJohn Edward Broadbent                                            resetType))
2773cc340dd9SEd Tanous             {
2774cc340dd9SEd Tanous                 return;
2775cc340dd9SEd Tanous             }
2776cc340dd9SEd Tanous 
2777d22c8396SJason M. Bills             // Get the command and host vs. chassis
2778cc340dd9SEd Tanous             std::string command;
2779543f4400SEd Tanous             bool hostCommand = true;
2780d4d25793SEd Tanous             if ((resetType == "On") || (resetType == "ForceOn"))
2781cc340dd9SEd Tanous             {
2782cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.On";
2783d22c8396SJason M. Bills                 hostCommand = true;
2784d22c8396SJason M. Bills             }
2785d22c8396SJason M. Bills             else if (resetType == "ForceOff")
2786d22c8396SJason M. Bills             {
2787d22c8396SJason M. Bills                 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2788d22c8396SJason M. Bills                 hostCommand = false;
2789d22c8396SJason M. Bills             }
2790d22c8396SJason M. Bills             else if (resetType == "ForceRestart")
2791d22c8396SJason M. Bills             {
279286a0851aSJason M. Bills                 command =
279386a0851aSJason M. Bills                     "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
279486a0851aSJason M. Bills                 hostCommand = true;
2795cc340dd9SEd Tanous             }
27969712f8acSEd Tanous             else if (resetType == "GracefulShutdown")
2797cc340dd9SEd Tanous             {
2798cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.Off";
2799d22c8396SJason M. Bills                 hostCommand = true;
2800cc340dd9SEd Tanous             }
28019712f8acSEd Tanous             else if (resetType == "GracefulRestart")
2802cc340dd9SEd Tanous             {
28030fda0f12SGeorge Liu                 command =
28040fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2805d22c8396SJason M. Bills                 hostCommand = true;
2806d22c8396SJason M. Bills             }
2807d22c8396SJason M. Bills             else if (resetType == "PowerCycle")
2808d22c8396SJason M. Bills             {
280986a0851aSJason M. Bills                 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
281086a0851aSJason M. Bills                 hostCommand = true;
2811cc340dd9SEd Tanous             }
2812bfd5b826SLakshminarayana R. Kammath             else if (resetType == "Nmi")
2813bfd5b826SLakshminarayana R. Kammath             {
2814bfd5b826SLakshminarayana R. Kammath                 doNMI(asyncResp);
2815bfd5b826SLakshminarayana R. Kammath                 return;
2816bfd5b826SLakshminarayana R. Kammath             }
2817cc340dd9SEd Tanous             else
2818cc340dd9SEd Tanous             {
28198d1b46d7Szhanghch05                 messages::actionParameterUnknown(asyncResp->res, "Reset",
28208d1b46d7Szhanghch05                                                  resetType);
2821cc340dd9SEd Tanous                 return;
2822cc340dd9SEd Tanous             }
2823cc340dd9SEd Tanous 
2824d22c8396SJason M. Bills             if (hostCommand)
2825d22c8396SJason M. Bills             {
2826cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
2827d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2828cc340dd9SEd Tanous                         if (ec)
2829cc340dd9SEd Tanous                         {
2830cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
28317e860f15SJohn Edward Broadbent                             if (ec.value() ==
28327e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2833d22c8396SJason M. Bills                             {
2834d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2835d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2836d22c8396SJason M. Bills                             }
2837d22c8396SJason M. Bills                             else
2838d22c8396SJason M. Bills                             {
2839f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
2840d22c8396SJason M. Bills                             }
2841cc340dd9SEd Tanous                             return;
2842cc340dd9SEd Tanous                         }
2843f12894f8SJason M. Bills                         messages::success(asyncResp->res);
2844cc340dd9SEd Tanous                     },
2845cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
2846cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
2847cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
28489712f8acSEd Tanous                     "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2849168e20c1SEd Tanous                     dbus::utility::DbusVariantType{command});
2850cc340dd9SEd Tanous             }
2851d22c8396SJason M. Bills             else
2852d22c8396SJason M. Bills             {
2853d22c8396SJason M. Bills                 crow::connections::systemBus->async_method_call(
2854d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2855d22c8396SJason M. Bills                         if (ec)
2856d22c8396SJason M. Bills                         {
2857d22c8396SJason M. Bills                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
28587e860f15SJohn Edward Broadbent                             if (ec.value() ==
28597e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2860d22c8396SJason M. Bills                             {
2861d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2862d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2863d22c8396SJason M. Bills                             }
2864d22c8396SJason M. Bills                             else
2865d22c8396SJason M. Bills                             {
2866d22c8396SJason M. Bills                                 messages::internalError(asyncResp->res);
2867d22c8396SJason M. Bills                             }
2868d22c8396SJason M. Bills                             return;
2869d22c8396SJason M. Bills                         }
2870d22c8396SJason M. Bills                         messages::success(asyncResp->res);
2871d22c8396SJason M. Bills                     },
2872d22c8396SJason M. Bills                     "xyz.openbmc_project.State.Chassis",
2873d22c8396SJason M. Bills                     "/xyz/openbmc_project/state/chassis0",
2874d22c8396SJason M. Bills                     "org.freedesktop.DBus.Properties", "Set",
28757e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.State.Chassis",
28767e860f15SJohn Edward Broadbent                     "RequestedPowerTransition",
2877168e20c1SEd Tanous                     dbus::utility::DbusVariantType{command});
2878d22c8396SJason M. Bills             }
28797e860f15SJohn Edward Broadbent         });
2880d22c8396SJason M. Bills }
2881cc340dd9SEd Tanous 
2882cc340dd9SEd Tanous /**
28836617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2884c5b2abe0SLewanczyk, Dawid  */
28857e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
28861abe55efSEd Tanous {
2887c5b2abe0SLewanczyk, Dawid 
2888c5b2abe0SLewanczyk, Dawid     /**
2889c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2890c5b2abe0SLewanczyk, Dawid      */
28917e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2892ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
28937e860f15SJohn Edward Broadbent         .methods(
28947e860f15SJohn Edward Broadbent             boost::beast::http::verb::
28957e860f15SJohn Edward Broadbent                 get)([](const crow::Request&,
28967e860f15SJohn Edward Broadbent                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28978d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.type"] =
289837bbf98cSChris Cain                 "#ComputerSystem.v1_16_0.ComputerSystem";
28998d1b46d7Szhanghch05             asyncResp->res.jsonValue["Name"] = "system";
29008d1b46d7Szhanghch05             asyncResp->res.jsonValue["Id"] = "system";
29018d1b46d7Szhanghch05             asyncResp->res.jsonValue["SystemType"] = "Physical";
29028d1b46d7Szhanghch05             asyncResp->res.jsonValue["Description"] = "Computer System";
29038d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
29048d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
29058d1b46d7Szhanghch05                 "Disabled";
29068d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
29078d1b46d7Szhanghch05                 uint64_t(0);
29088d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
29098d1b46d7Szhanghch05                 "Disabled";
29107e860f15SJohn Edward Broadbent             asyncResp->res.jsonValue["@odata.id"] =
29117e860f15SJohn Edward Broadbent                 "/redfish/v1/Systems/system";
291204a258f4SEd Tanous 
29138d1b46d7Szhanghch05             asyncResp->res.jsonValue["Processors"] = {
2914029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
29158d1b46d7Szhanghch05             asyncResp->res.jsonValue["Memory"] = {
2916029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
29178d1b46d7Szhanghch05             asyncResp->res.jsonValue["Storage"] = {
2918a25aeccfSNikhil Potade                 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
2919029573d4SEd Tanous 
29208d1b46d7Szhanghch05             asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
2921cc340dd9SEd Tanous                 {"target",
2922029573d4SEd Tanous                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
29231cb1a9e6SAppaRao Puli                 {"@Redfish.ActionInfo",
29241cb1a9e6SAppaRao Puli                  "/redfish/v1/Systems/system/ResetActionInfo"}};
2925c5b2abe0SLewanczyk, Dawid 
29268d1b46d7Szhanghch05             asyncResp->res.jsonValue["LogServices"] = {
2927029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
2928c4bf6374SJason M. Bills 
29298d1b46d7Szhanghch05             asyncResp->res.jsonValue["Bios"] = {
2930d82a3acdSCarol Wang                 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
2931d82a3acdSCarol Wang 
29328d1b46d7Szhanghch05             asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
2933c5d03ff4SJennifer Lee                 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
2934c5d03ff4SJennifer Lee 
29358d1b46d7Szhanghch05             asyncResp->res.jsonValue["Status"] = {
2936c5d03ff4SJennifer Lee                 {"Health", "OK"},
2937c5d03ff4SJennifer Lee                 {"State", "Enabled"},
2938c5d03ff4SJennifer Lee             };
29390e8ac5e7SGunnar Mills 
29400e8ac5e7SGunnar Mills             // Fill in SerialConsole info
29410e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
29420e8ac5e7SGunnar Mills                 15;
29430e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = {
29440e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
29450e8ac5e7SGunnar Mills             };
29460e8ac5e7SGunnar Mills             // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
29470e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["SSH"] = {
29480e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
29490e8ac5e7SGunnar Mills                 {"Port", 2200},
29500e8ac5e7SGunnar Mills                 // https://github.com/openbmc/docs/blob/master/console.md
29510e8ac5e7SGunnar Mills                 {"HotKeySequenceDisplay", "Press ~. to exit console"},
29520e8ac5e7SGunnar Mills             };
29530e8ac5e7SGunnar Mills 
29540e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
29550e8ac5e7SGunnar Mills             // Fill in GraphicalConsole info
29560e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["GraphicalConsole"] = {
29570e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
29580e8ac5e7SGunnar Mills                 {"MaxConcurrentSessions", 4},
29590e8ac5e7SGunnar Mills                 {"ConnectTypesSupported", {"KVMIP"}},
29600e8ac5e7SGunnar Mills             };
29610e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
2962e284a7c1SJames Feist             constexpr const std::array<const char*, 4> inventoryForSystems = {
2963b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
29642ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
2965e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
2966e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
2967b49ac873SJames Feist 
2968b49ac873SJames Feist             auto health = std::make_shared<HealthPopulate>(asyncResp);
2969b49ac873SJames Feist             crow::connections::systemBus->async_method_call(
2970b49ac873SJames Feist                 [health](const boost::system::error_code ec,
2971914e2d5dSEd Tanous                          const std::vector<std::string>& resp) {
2972b49ac873SJames Feist                     if (ec)
2973b49ac873SJames Feist                     {
2974b49ac873SJames Feist                         // no inventory
2975b49ac873SJames Feist                         return;
2976b49ac873SJames Feist                     }
2977b49ac873SJames Feist 
2978914e2d5dSEd Tanous                     health->inventory = resp;
2979b49ac873SJames Feist                 },
2980b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper",
2981b49ac873SJames Feist                 "/xyz/openbmc_project/object_mapper",
2982b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2983b49ac873SJames Feist                 int32_t(0), inventoryForSystems);
2984b49ac873SJames Feist 
2985b49ac873SJames Feist             health->populate();
2986b49ac873SJames Feist 
29878d1b46d7Szhanghch05             getMainChassisId(
29888d1b46d7Szhanghch05                 asyncResp, [](const std::string& chassisId,
29898d1b46d7Szhanghch05                               const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2990c5d03ff4SJennifer Lee                     aRsp->res.jsonValue["Links"]["Chassis"] = {
2991c5d03ff4SJennifer Lee                         {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
2992c5d03ff4SJennifer Lee                 });
2993a3002228SAppaRao Puli 
29949f8bfa7cSGunnar Mills             getLocationIndicatorActive(asyncResp);
29959f8bfa7cSGunnar Mills             // TODO (Gunnar): Remove IndicatorLED after enough time has passed
2996a3002228SAppaRao Puli             getIndicatorLedState(asyncResp);
29975bc2dc8eSJames Feist             getComputerSystem(asyncResp, health);
29986c34de48SEd Tanous             getHostState(asyncResp);
2999491d8ee7SSantosh Puranik             getBootProperties(asyncResp);
3000978b8803SAndrew Geissler             getBootProgress(asyncResp);
3001adbe192aSJason M. Bills             getPCIeDeviceList(asyncResp, "PCIeDevices");
300251709ffdSYong Li             getHostWatchdogTimer(asyncResp);
3003c6a620f2SGeorge Liu             getPowerRestorePolicy(asyncResp);
30046bd5a8d2SGunnar Mills             getAutomaticRetry(asyncResp);
3005c0557e1aSGunnar Mills             getLastResetTime(asyncResp);
3006a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3007a6349918SAppaRao Puli             getProvisioningStatus(asyncResp);
3008a6349918SAppaRao Puli #endif
30091981771bSAli Ahmed             getTrustedModuleRequiredToBoot(asyncResp);
30103a2d0424SChris Cain             getPowerMode(asyncResp);
301137bbf98cSChris Cain             getIdlePowerSaver(asyncResp);
30127e860f15SJohn Edward Broadbent         });
30137e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3014ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
30157e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
30167e860f15SJohn Edward Broadbent             [](const crow::Request& req,
30177e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
30189f8bfa7cSGunnar Mills                 std::optional<bool> locationIndicatorActive;
3019cde19e5fSSantosh Puranik                 std::optional<std::string> indicatorLed;
3020491d8ee7SSantosh Puranik                 std::optional<nlohmann::json> bootProps;
3021c45f0082SYong Li                 std::optional<nlohmann::json> wdtTimerProps;
302298e386ecSGunnar Mills                 std::optional<std::string> assetTag;
3023c6a620f2SGeorge Liu                 std::optional<std::string> powerRestorePolicy;
30243a2d0424SChris Cain                 std::optional<std::string> powerMode;
302537bbf98cSChris Cain                 std::optional<nlohmann::json> ipsProps;
302615ed6780SWilly Tu                 if (!json_util::readJsonPatch(
30278d1b46d7Szhanghch05                         req, asyncResp->res, "IndicatorLED", indicatorLed,
30287e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
30297e860f15SJohn Edward Broadbent                         "Boot", bootProps, "WatchdogTimer", wdtTimerProps,
30307e860f15SJohn Edward Broadbent                         "PowerRestorePolicy", powerRestorePolicy, "AssetTag",
303137bbf98cSChris Cain                         assetTag, "PowerMode", powerMode, "IdlePowerSaver",
303237bbf98cSChris Cain                         ipsProps))
30336617338dSEd Tanous                 {
30346617338dSEd Tanous                     return;
30356617338dSEd Tanous                 }
3036491d8ee7SSantosh Puranik 
30378d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
3038c45f0082SYong Li 
303998e386ecSGunnar Mills                 if (assetTag)
304098e386ecSGunnar Mills                 {
304198e386ecSGunnar Mills                     setAssetTag(asyncResp, *assetTag);
304298e386ecSGunnar Mills                 }
304398e386ecSGunnar Mills 
3044c45f0082SYong Li                 if (wdtTimerProps)
3045c45f0082SYong Li                 {
3046c45f0082SYong Li                     std::optional<bool> wdtEnable;
3047c45f0082SYong Li                     std::optional<std::string> wdtTimeOutAction;
3048c45f0082SYong Li 
3049c45f0082SYong Li                     if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
3050c45f0082SYong Li                                              "FunctionEnabled", wdtEnable,
3051c45f0082SYong Li                                              "TimeoutAction", wdtTimeOutAction))
3052c45f0082SYong Li                     {
3053c45f0082SYong Li                         return;
3054c45f0082SYong Li                     }
3055f23b7296SEd Tanous                     setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3056c45f0082SYong Li                 }
3057c45f0082SYong Li 
3058491d8ee7SSantosh Puranik                 if (bootProps)
3059491d8ee7SSantosh Puranik                 {
3060491d8ee7SSantosh Puranik                     std::optional<std::string> bootSource;
3061cd9a4666SKonstantin Aladyshev                     std::optional<std::string> bootType;
3062491d8ee7SSantosh Puranik                     std::optional<std::string> bootEnable;
306369f35306SGunnar Mills                     std::optional<std::string> automaticRetryConfig;
3064ac7e1e0bSAli Ahmed                     std::optional<bool> trustedModuleRequiredToBoot;
3065491d8ee7SSantosh Puranik 
306669f35306SGunnar Mills                     if (!json_util::readJson(
30677e860f15SJohn Edward Broadbent                             *bootProps, asyncResp->res,
30687e860f15SJohn Edward Broadbent                             "BootSourceOverrideTarget", bootSource,
3069cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode", bootType,
30707e860f15SJohn Edward Broadbent                             "BootSourceOverrideEnabled", bootEnable,
3071ac7e1e0bSAli Ahmed                             "AutomaticRetryConfig", automaticRetryConfig,
3072ac7e1e0bSAli Ahmed                             "TrustedModuleRequiredToBoot",
3073ac7e1e0bSAli Ahmed                             trustedModuleRequiredToBoot))
3074491d8ee7SSantosh Puranik                     {
3075491d8ee7SSantosh Puranik                         return;
3076491d8ee7SSantosh Puranik                     }
3077c21865c4SKonstantin Aladyshev 
3078cd9a4666SKonstantin Aladyshev                     if (bootSource || bootType || bootEnable)
307969f35306SGunnar Mills                     {
3080c21865c4SKonstantin Aladyshev                         setBootProperties(asyncResp, bootSource, bootType,
3081c21865c4SKonstantin Aladyshev                                           bootEnable);
3082491d8ee7SSantosh Puranik                     }
308369f35306SGunnar Mills                     if (automaticRetryConfig)
308469f35306SGunnar Mills                     {
3085f23b7296SEd Tanous                         setAutomaticRetry(asyncResp, *automaticRetryConfig);
308669f35306SGunnar Mills                     }
3087ac7e1e0bSAli Ahmed 
3088ac7e1e0bSAli Ahmed                     if (trustedModuleRequiredToBoot)
3089ac7e1e0bSAli Ahmed                     {
3090ac7e1e0bSAli Ahmed                         setTrustedModuleRequiredToBoot(
3091ac7e1e0bSAli Ahmed                             asyncResp, *trustedModuleRequiredToBoot);
3092ac7e1e0bSAli Ahmed                     }
309369f35306SGunnar Mills                 }
3094265c1602SJohnathan Mantey 
30959f8bfa7cSGunnar Mills                 if (locationIndicatorActive)
30969f8bfa7cSGunnar Mills                 {
30977e860f15SJohn Edward Broadbent                     setLocationIndicatorActive(asyncResp,
30987e860f15SJohn Edward Broadbent                                                *locationIndicatorActive);
30999f8bfa7cSGunnar Mills                 }
31009f8bfa7cSGunnar Mills 
31017e860f15SJohn Edward Broadbent                 // TODO (Gunnar): Remove IndicatorLED after enough time has
31027e860f15SJohn Edward Broadbent                 // passed
31039712f8acSEd Tanous                 if (indicatorLed)
31046617338dSEd Tanous                 {
3105f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
31067e860f15SJohn Edward Broadbent                     asyncResp->res.addHeader(
31077e860f15SJohn Edward Broadbent                         boost::beast::http::field::warning,
3108d6aa0093SGunnar Mills                         "299 - \"IndicatorLED is deprecated. Use "
3109d6aa0093SGunnar Mills                         "LocationIndicatorActive instead.\"");
31106617338dSEd Tanous                 }
3111c6a620f2SGeorge Liu 
3112c6a620f2SGeorge Liu                 if (powerRestorePolicy)
3113c6a620f2SGeorge Liu                 {
31144e69c904SGunnar Mills                     setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3115c6a620f2SGeorge Liu                 }
31163a2d0424SChris Cain 
31173a2d0424SChris Cain                 if (powerMode)
31183a2d0424SChris Cain                 {
31193a2d0424SChris Cain                     setPowerMode(asyncResp, *powerMode);
31203a2d0424SChris Cain                 }
312137bbf98cSChris Cain 
312237bbf98cSChris Cain                 if (ipsProps)
312337bbf98cSChris Cain                 {
312437bbf98cSChris Cain                     std::optional<bool> ipsEnable;
312537bbf98cSChris Cain                     std::optional<uint8_t> ipsEnterUtil;
312637bbf98cSChris Cain                     std::optional<uint64_t> ipsEnterTime;
312737bbf98cSChris Cain                     std::optional<uint8_t> ipsExitUtil;
312837bbf98cSChris Cain                     std::optional<uint64_t> ipsExitTime;
312937bbf98cSChris Cain 
313037bbf98cSChris Cain                     if (!json_util::readJson(
313137bbf98cSChris Cain                             *ipsProps, asyncResp->res, "Enabled", ipsEnable,
313237bbf98cSChris Cain                             "EnterUtilizationPercent", ipsEnterUtil,
313337bbf98cSChris Cain                             "EnterDwellTimeSeconds", ipsEnterTime,
313437bbf98cSChris Cain                             "ExitUtilizationPercent", ipsExitUtil,
313537bbf98cSChris Cain                             "ExitDwellTimeSeconds", ipsExitTime))
313637bbf98cSChris Cain                     {
313737bbf98cSChris Cain                         return;
313837bbf98cSChris Cain                     }
313937bbf98cSChris Cain                     setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil,
314037bbf98cSChris Cain                                       ipsEnterTime, ipsExitUtil, ipsExitTime);
314137bbf98cSChris Cain                 }
31427e860f15SJohn Edward Broadbent             });
3143c5b2abe0SLewanczyk, Dawid }
31441cb1a9e6SAppaRao Puli 
31451cb1a9e6SAppaRao Puli /**
31461cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
31471cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
31481cb1a9e6SAppaRao Puli  */
31497e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
31501cb1a9e6SAppaRao Puli {
31511cb1a9e6SAppaRao Puli 
31521cb1a9e6SAppaRao Puli     /**
31531cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
31541cb1a9e6SAppaRao Puli      */
31557e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3156ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
31577e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
31587e860f15SJohn Edward Broadbent             [](const crow::Request&,
31597e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
31608d1b46d7Szhanghch05                 asyncResp->res.jsonValue = {
31611cb1a9e6SAppaRao Puli                     {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
31621cb1a9e6SAppaRao Puli                     {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
31631cb1a9e6SAppaRao Puli                     {"Name", "Reset Action Info"},
31641cb1a9e6SAppaRao Puli                     {"Id", "ResetActionInfo"},
31651cb1a9e6SAppaRao Puli                     {"Parameters",
31661cb1a9e6SAppaRao Puli                      {{{"Name", "ResetType"},
31671cb1a9e6SAppaRao Puli                        {"Required", true},
31681cb1a9e6SAppaRao Puli                        {"DataType", "String"},
31691cb1a9e6SAppaRao Puli                        {"AllowableValues",
31707e860f15SJohn Edward Broadbent                         {"On", "ForceOff", "ForceOn", "ForceRestart",
31717e860f15SJohn Edward Broadbent                          "GracefulRestart", "GracefulShutdown", "PowerCycle",
31727e860f15SJohn Edward Broadbent                          "Nmi"}}}}}};
31737e860f15SJohn Edward Broadbent             });
31741cb1a9e6SAppaRao Puli }
3175c5b2abe0SLewanczyk, Dawid } // namespace redfish
3176