xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 2b82937ecef572954b49569177b16831cbc09cfe)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
181e1e598dSJonathan Doman #include "dbus_singleton.hpp"
19b49ac873SJames Feist #include "health.hpp"
201c8fba97SJames Feist #include "led.hpp"
21f5c9f8bdSJason M. Bills #include "pcie.hpp"
22f4c99e70SEd Tanous #include "query.hpp"
23c5d03ff4SJennifer Lee #include "redfish_util.hpp"
24*2b82937eSEd Tanous #include "utils/time_utils.hpp"
25c5d03ff4SJennifer Lee 
267e860f15SJohn Edward Broadbent #include <app.hpp>
279712f8acSEd Tanous #include <boost/container/flat_map.hpp>
28168e20c1SEd Tanous #include <dbus_utility.hpp>
29ed398213SEd Tanous #include <registries/privilege_registry.hpp>
301e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
31c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
32eee0013eSWilly Tu #include <utils/sw_utils.hpp>
331214b7e7SGunnar Mills 
34abf2add6SEd Tanous #include <variant>
35c5b2abe0SLewanczyk, Dawid 
361abe55efSEd Tanous namespace redfish
371abe55efSEd Tanous {
38c5b2abe0SLewanczyk, Dawid 
399d3ae10eSAlpana Kumari /**
409d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
419d3ae10eSAlpana Kumari  *
429d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
439d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
449d3ae10eSAlpana Kumari  *
459d3ae10eSAlpana Kumari  * @return None.
469d3ae10eSAlpana Kumari  */
478d1b46d7Szhanghch05 inline void
488d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
491e1e598dSJonathan Doman                          bool isDimmFunctional)
509d3ae10eSAlpana Kumari {
511e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
529d3ae10eSAlpana Kumari 
539d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
549d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
559d3ae10eSAlpana Kumari     // ENABLED.
5602cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
579d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
589d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
599d3ae10eSAlpana Kumari     {
60e05aec50SEd Tanous         if (isDimmFunctional)
619d3ae10eSAlpana Kumari         {
629d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
639d3ae10eSAlpana Kumari                 "Enabled";
649d3ae10eSAlpana Kumari         }
659d3ae10eSAlpana Kumari     }
669d3ae10eSAlpana Kumari }
679d3ae10eSAlpana Kumari 
6857e8c9beSAlpana Kumari /*
6957e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
7057e8c9beSAlpana Kumari  *
7157e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
7257e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
7357e8c9beSAlpana Kumari  *
7457e8c9beSAlpana Kumari  * @return None.
7557e8c9beSAlpana Kumari  */
761e1e598dSJonathan Doman inline void
771e1e598dSJonathan Doman     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
781e1e598dSJonathan Doman                            bool isCpuPresent)
7957e8c9beSAlpana Kumari {
801e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
8157e8c9beSAlpana Kumari 
8255f79e6fSEd Tanous     if (isCpuPresent)
8357e8c9beSAlpana Kumari     {
84b4b9595aSJames Feist         nlohmann::json& procCount =
85b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
8655f79e6fSEd Tanous         auto* procCountPtr =
87b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
88b4b9595aSJames Feist         if (procCountPtr != nullptr)
89b4b9595aSJames Feist         {
90b4b9595aSJames Feist             // shouldn't be possible to be nullptr
91b4b9595aSJames Feist             *procCountPtr += 1;
9257e8c9beSAlpana Kumari         }
93b4b9595aSJames Feist     }
9457e8c9beSAlpana Kumari }
9557e8c9beSAlpana Kumari 
9657e8c9beSAlpana Kumari /*
9757e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9857e8c9beSAlpana Kumari  *        CPU Functional State
9957e8c9beSAlpana Kumari  *
10057e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
10157e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
10257e8c9beSAlpana Kumari  *
10357e8c9beSAlpana Kumari  * @return None.
10457e8c9beSAlpana Kumari  */
1051e1e598dSJonathan Doman inline void
1061e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1071e1e598dSJonathan Doman                              bool isCpuFunctional)
10857e8c9beSAlpana Kumari {
1091e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
11057e8c9beSAlpana Kumari 
11102cad96eSEd Tanous     const nlohmann::json& prevProcState =
11257e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
11357e8c9beSAlpana Kumari 
11457e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
11557e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
11657e8c9beSAlpana Kumari     // Functional.
11757e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11857e8c9beSAlpana Kumari     {
119e05aec50SEd Tanous         if (isCpuFunctional)
12057e8c9beSAlpana Kumari         {
12157e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
12257e8c9beSAlpana Kumari                 "Enabled";
12357e8c9beSAlpana Kumari         }
12457e8c9beSAlpana Kumari     }
12557e8c9beSAlpana Kumari }
12657e8c9beSAlpana Kumari 
127b9d36b47SEd Tanous inline void
128b9d36b47SEd Tanous     getProcessorProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
129b9d36b47SEd Tanous                            const std::string& service, const std::string& path,
130b9d36b47SEd Tanous                            const dbus::utility::DBusPropertiesMap& properties)
13103fbed92SAli Ahmed {
13203fbed92SAli Ahmed 
13303fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
13403fbed92SAli Ahmed 
1351e1e598dSJonathan Doman     auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
1361e1e598dSJonathan Doman                                        const bool cpuPresenceCheck) {
13703fbed92SAli Ahmed         if (ec3)
13803fbed92SAli Ahmed         {
13903fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
14003fbed92SAli Ahmed             return;
14103fbed92SAli Ahmed         }
14203fbed92SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
14303fbed92SAli Ahmed     };
14403fbed92SAli Ahmed 
1451e1e598dSJonathan Doman     auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
1461e1e598dSJonathan Doman                                          const bool cpuFunctionalCheck) {
14703fbed92SAli Ahmed         if (ec3)
14803fbed92SAli Ahmed         {
14903fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
15003fbed92SAli Ahmed             return;
15103fbed92SAli Ahmed         }
15203fbed92SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
15303fbed92SAli Ahmed     };
15403fbed92SAli Ahmed 
15503fbed92SAli Ahmed     // Get the Presence of CPU
1561e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
1571e1e598dSJonathan Doman         *crow::connections::systemBus, service, path,
1581e1e598dSJonathan Doman         "xyz.openbmc_project.Inventory.Item", "Present",
1591e1e598dSJonathan Doman         std::move(getCpuPresenceState));
16003fbed92SAli Ahmed 
16103fbed92SAli Ahmed     // Get the Functional State
1621e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
1631e1e598dSJonathan Doman         *crow::connections::systemBus, service, path,
1641e1e598dSJonathan Doman         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
1651e1e598dSJonathan Doman         std::move(getCpuFunctionalState));
16603fbed92SAli Ahmed 
16703fbed92SAli Ahmed     for (const auto& property : properties)
16803fbed92SAli Ahmed     {
16903fbed92SAli Ahmed 
17003fbed92SAli Ahmed         // TODO: Get Model
17103fbed92SAli Ahmed 
17203fbed92SAli Ahmed         // Get CoreCount
17303fbed92SAli Ahmed         if (property.first == "CoreCount")
17403fbed92SAli Ahmed         {
17503fbed92SAli Ahmed 
17603fbed92SAli Ahmed             // Get CPU CoreCount and add it to the total
17703fbed92SAli Ahmed             const uint16_t* coreCountVal =
17803fbed92SAli Ahmed                 std::get_if<uint16_t>(&property.second);
17903fbed92SAli Ahmed 
180e662eae8SEd Tanous             if (coreCountVal == nullptr)
18103fbed92SAli Ahmed             {
18203fbed92SAli Ahmed                 messages::internalError(aResp->res);
18303fbed92SAli Ahmed                 return;
18403fbed92SAli Ahmed             }
18503fbed92SAli Ahmed 
18603fbed92SAli Ahmed             nlohmann::json& coreCount =
18703fbed92SAli Ahmed                 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
18803fbed92SAli Ahmed             uint64_t* coreCountPtr = coreCount.get_ptr<uint64_t*>();
18903fbed92SAli Ahmed 
19003fbed92SAli Ahmed             if (coreCountPtr == nullptr)
19103fbed92SAli Ahmed             {
192a6669023SKrzysztof Grobelny                 coreCount = *coreCountVal;
19303fbed92SAli Ahmed             }
19403fbed92SAli Ahmed             else
19503fbed92SAli Ahmed             {
19603fbed92SAli Ahmed                 *coreCountPtr += *coreCountVal;
19703fbed92SAli Ahmed             }
19803fbed92SAli Ahmed         }
19903fbed92SAli Ahmed     }
20003fbed92SAli Ahmed }
20103fbed92SAli Ahmed 
20203fbed92SAli Ahmed /*
20303fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
20403fbed92SAli Ahmed  *
20503fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
20603fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
20703fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
20803fbed92SAli Ahmed  *
20903fbed92SAli Ahmed  * @return None.
21003fbed92SAli Ahmed  */
21103fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21203fbed92SAli Ahmed                                 const std::string& service,
21303fbed92SAli Ahmed                                 const std::string& path)
21403fbed92SAli Ahmed {
21503fbed92SAli Ahmed 
21603fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
21703fbed92SAli Ahmed         [aResp, service,
21803fbed92SAli Ahmed          path](const boost::system::error_code ec2,
219b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& 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(
247b9d36b47SEd Tanous         [aResp,
248b9d36b47SEd Tanous          systemHealth](const boost::system::error_code ec,
249b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
2501abe55efSEd Tanous         if (ec)
2511abe55efSEd Tanous         {
25255c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
253f12894f8SJason M. Bills             messages::internalError(aResp->res);
254c5b2abe0SLewanczyk, Dawid             return;
255c5b2abe0SLewanczyk, Dawid         }
256c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
257002d39b4SEd Tanous         for (const std::pair<
258002d39b4SEd Tanous                  std::string,
259002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
2601214b7e7SGunnar Mills                  object : subtree)
2611abe55efSEd Tanous         {
262c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
26355c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
264002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
2651214b7e7SGunnar Mills                 connectionNames = object.second;
26626f6976fSEd Tanous             if (connectionNames.empty())
2671abe55efSEd Tanous             {
268c5b2abe0SLewanczyk, Dawid                 continue;
269c5b2abe0SLewanczyk, Dawid             }
270029573d4SEd Tanous 
2715bc2dc8eSJames Feist             auto memoryHealth = std::make_shared<HealthPopulate>(
272dfababfcSNan Zhou                 aResp, "/MemorySummary/Status"_json_pointer);
2735bc2dc8eSJames Feist 
2745bc2dc8eSJames Feist             auto cpuHealth = std::make_shared<HealthPopulate>(
275dfababfcSNan Zhou                 aResp, "/ProcessorSummary/Status"_json_pointer);
2765bc2dc8eSJames Feist 
2775bc2dc8eSJames Feist             systemHealth->children.emplace_back(memoryHealth);
2785bc2dc8eSJames Feist             systemHealth->children.emplace_back(cpuHealth);
2795bc2dc8eSJames Feist 
2806c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
2816c34de48SEd Tanous             // BiosVer
28204a258f4SEd Tanous             for (const auto& connection : connectionNames)
2831abe55efSEd Tanous             {
28404a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
2851abe55efSEd Tanous                 {
28604a258f4SEd Tanous                     if (interfaceName ==
28704a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
2881abe55efSEd Tanous                     {
2891abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
29004a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
2919d3ae10eSAlpana Kumari 
29255c7b7a2SEd Tanous                         crow::connections::systemBus->async_method_call(
2939d3ae10eSAlpana Kumari                             [aResp, service{connection.first},
294f23b7296SEd Tanous                              path](const boost::system::error_code ec2,
295b9d36b47SEd Tanous                                    const dbus::utility::DBusPropertiesMap&
2961214b7e7SGunnar Mills                                        properties) {
297cb13a392SEd Tanous                             if (ec2)
2981abe55efSEd Tanous                             {
299002d39b4SEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error "
300002d39b4SEd Tanous                                                  << ec2;
301f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
302c5b2abe0SLewanczyk, Dawid                                 return;
303c5b2abe0SLewanczyk, Dawid                             }
304002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
305c5b2abe0SLewanczyk, Dawid                                              << " Dimm properties.";
3069d3ae10eSAlpana Kumari 
30726f6976fSEd Tanous                             if (!properties.empty())
3089d3ae10eSAlpana Kumari                             {
309168e20c1SEd Tanous                                 for (const std::pair<
310168e20c1SEd Tanous                                          std::string,
311002d39b4SEd Tanous                                          dbus::utility::DbusVariantType>&
3121214b7e7SGunnar Mills                                          property : properties)
3131abe55efSEd Tanous                                 {
314002d39b4SEd Tanous                                     if (property.first != "MemorySizeInKB")
3151abe55efSEd Tanous                                     {
3165fd7ba65SCheng C Yang                                         continue;
3175fd7ba65SCheng C Yang                                     }
3185fd7ba65SCheng C Yang                                     const uint32_t* value =
319002d39b4SEd Tanous                                         std::get_if<uint32_t>(&property.second);
3205fd7ba65SCheng C Yang                                     if (value == nullptr)
3211abe55efSEd Tanous                                     {
3225fd7ba65SCheng C Yang                                         BMCWEB_LOG_DEBUG
3230fda0f12SGeorge Liu                                             << "Find incorrect type of MemorySize";
3245fd7ba65SCheng C Yang                                         continue;
3255fd7ba65SCheng C Yang                                     }
3265fd7ba65SCheng C Yang                                     nlohmann::json& totalMemory =
327002d39b4SEd Tanous                                         aResp->res
328002d39b4SEd Tanous                                             .jsonValue["MemorySummary"]
3290fda0f12SGeorge Liu                                                       ["TotalSystemMemoryGiB"];
33002cad96eSEd Tanous                                     const uint64_t* preValue =
33102cad96eSEd Tanous                                         totalMemory.get_ptr<const uint64_t*>();
3325fd7ba65SCheng C Yang                                     if (preValue == nullptr)
3335fd7ba65SCheng C Yang                                     {
3345fd7ba65SCheng C Yang                                         continue;
3355fd7ba65SCheng C Yang                                     }
3365fd7ba65SCheng C Yang                                     aResp->res
3375fd7ba65SCheng C Yang                                         .jsonValue["MemorySummary"]
338002d39b4SEd Tanous                                                   ["TotalSystemMemoryGiB"] =
339002d39b4SEd Tanous                                         *value / (1024 * 1024) + *preValue;
340002d39b4SEd Tanous                                     aResp->res.jsonValue["MemorySummary"]
3419d3ae10eSAlpana Kumari                                                         ["Status"]["State"] =
3421abe55efSEd Tanous                                         "Enabled";
343c5b2abe0SLewanczyk, Dawid                                 }
344c5b2abe0SLewanczyk, Dawid                             }
3459d3ae10eSAlpana Kumari                             else
3469d3ae10eSAlpana Kumari                             {
3471e1e598dSJonathan Doman                                 sdbusplus::asio::getProperty<bool>(
348002d39b4SEd Tanous                                     *crow::connections::systemBus, service,
349002d39b4SEd Tanous                                     path,
3501e1e598dSJonathan Doman                                     "xyz.openbmc_project.State."
3511e1e598dSJonathan Doman                                     "Decorator.OperationalStatus",
3521e1e598dSJonathan Doman                                     "Functional",
353002d39b4SEd Tanous                                     [aResp](const boost::system::error_code ec3,
3541e1e598dSJonathan Doman                                             bool dimmState) {
355cb13a392SEd Tanous                                     if (ec3)
3569d3ae10eSAlpana Kumari                                     {
3579d3ae10eSAlpana Kumari                                         BMCWEB_LOG_ERROR
358002d39b4SEd Tanous                                             << "DBUS response error " << ec3;
3599d3ae10eSAlpana Kumari                                         return;
3609d3ae10eSAlpana Kumari                                     }
361002d39b4SEd Tanous                                     updateDimmProperties(aResp, dimmState);
3621e1e598dSJonathan Doman                                     });
3639d3ae10eSAlpana Kumari                             }
364c5b2abe0SLewanczyk, Dawid                             },
36504a258f4SEd Tanous                             connection.first, path,
3666c34de48SEd Tanous                             "org.freedesktop.DBus.Properties", "GetAll",
3676c34de48SEd Tanous                             "xyz.openbmc_project.Inventory.Item.Dimm");
3685bc2dc8eSJames Feist 
3695bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
3701abe55efSEd Tanous                     }
37104a258f4SEd Tanous                     else if (interfaceName ==
37204a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
3731abe55efSEd Tanous                     {
3741abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
37504a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
37657e8c9beSAlpana Kumari 
37703fbed92SAli Ahmed                         getProcessorSummary(aResp, connection.first, path);
3785bc2dc8eSJames Feist 
3795bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
3801abe55efSEd Tanous                     }
381002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
3821abe55efSEd Tanous                     {
3831abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
38404a258f4SEd Tanous                             << "Found UUID, now get its properties.";
38555c7b7a2SEd Tanous                         crow::connections::systemBus->async_method_call(
386168e20c1SEd Tanous                             [aResp](const boost::system::error_code ec3,
387b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
3881214b7e7SGunnar Mills                                         properties) {
389cb13a392SEd Tanous                             if (ec3)
3901abe55efSEd Tanous                             {
391002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
392002d39b4SEd Tanous                                                  << ec3;
393f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
394c5b2abe0SLewanczyk, Dawid                                 return;
395c5b2abe0SLewanczyk, Dawid                             }
396002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
397c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
398168e20c1SEd Tanous                             for (const std::pair<
399168e20c1SEd Tanous                                      std::string,
400002d39b4SEd Tanous                                      dbus::utility::DbusVariantType>& property :
401002d39b4SEd Tanous                                  properties)
4021abe55efSEd Tanous                             {
40304a258f4SEd Tanous                                 if (property.first == "UUID")
4041abe55efSEd Tanous                                 {
405c5b2abe0SLewanczyk, Dawid                                     const std::string* value =
4068d78b7a9SPatrick Williams                                         std::get_if<std::string>(
4071b6b96c5SEd Tanous                                             &property.second);
40804a258f4SEd Tanous 
4091abe55efSEd Tanous                                     if (value != nullptr)
4101abe55efSEd Tanous                                     {
411029573d4SEd Tanous                                         std::string valueStr = *value;
41204a258f4SEd Tanous                                         if (valueStr.size() == 32)
4131abe55efSEd Tanous                                         {
414029573d4SEd Tanous                                             valueStr.insert(8, 1, '-');
415029573d4SEd Tanous                                             valueStr.insert(13, 1, '-');
416029573d4SEd Tanous                                             valueStr.insert(18, 1, '-');
417029573d4SEd Tanous                                             valueStr.insert(23, 1, '-');
41804a258f4SEd Tanous                                         }
419029573d4SEd Tanous                                         BMCWEB_LOG_DEBUG << "UUID = "
42004a258f4SEd Tanous                                                          << valueStr;
421002d39b4SEd Tanous                                         aResp->res.jsonValue["UUID"] = valueStr;
422c5b2abe0SLewanczyk, Dawid                                     }
423c5b2abe0SLewanczyk, Dawid                                 }
424c5b2abe0SLewanczyk, Dawid                             }
425c5b2abe0SLewanczyk, Dawid                             },
42604a258f4SEd Tanous                             connection.first, path,
4276c34de48SEd Tanous                             "org.freedesktop.DBus.Properties", "GetAll",
4281abe55efSEd Tanous                             "xyz.openbmc_project.Common.UUID");
429c5b2abe0SLewanczyk, Dawid                     }
430029573d4SEd Tanous                     else if (interfaceName ==
431029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4321abe55efSEd Tanous                     {
433029573d4SEd Tanous                         crow::connections::systemBus->async_method_call(
434168e20c1SEd Tanous                             [aResp](const boost::system::error_code ec2,
435b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4361214b7e7SGunnar Mills                                         propertiesList) {
437cb13a392SEd Tanous                             if (ec2)
438029573d4SEd Tanous                             {
439e4a4b9a9SJames Feist                                 // doesn't have to include this
440e4a4b9a9SJames Feist                                 // interface
441029573d4SEd Tanous                                 return;
442029573d4SEd Tanous                             }
443002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
444029573d4SEd Tanous                                              << " properties for system";
445168e20c1SEd Tanous                             for (const std::pair<
446168e20c1SEd Tanous                                      std::string,
447002d39b4SEd Tanous                                      dbus::utility::DbusVariantType>& property :
448002d39b4SEd Tanous                                  propertiesList)
449029573d4SEd Tanous                             {
450fc5afcf9Sbeccabroek                                 const std::string& propertyName =
451fc5afcf9Sbeccabroek                                     property.first;
452fc5afcf9Sbeccabroek                                 if ((propertyName == "PartNumber") ||
453fc5afcf9Sbeccabroek                                     (propertyName == "SerialNumber") ||
454fc5afcf9Sbeccabroek                                     (propertyName == "Manufacturer") ||
4555235d964SSunnySrivastava1984                                     (propertyName == "Model") ||
4565235d964SSunnySrivastava1984                                     (propertyName == "SubModel"))
457fc5afcf9Sbeccabroek                                 {
458029573d4SEd Tanous                                     const std::string* value =
459fc5afcf9Sbeccabroek                                         std::get_if<std::string>(
460029573d4SEd Tanous                                             &property.second);
461029573d4SEd Tanous                                     if (value != nullptr)
462029573d4SEd Tanous                                     {
463002d39b4SEd Tanous                                         aResp->res.jsonValue[propertyName] =
464029573d4SEd Tanous                                             *value;
465029573d4SEd Tanous                                     }
466029573d4SEd Tanous                                 }
467fc5afcf9Sbeccabroek                             }
468c1e236a6SGunnar Mills 
469cb7e1e7bSAndrew Geissler                             // Grab the bios version
470eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
471eee0013eSWilly Tu                                 aResp, sw_util::biosPurpose, "BiosVersion",
472002d39b4SEd Tanous                                 false);
473029573d4SEd Tanous                             },
474029573d4SEd Tanous                             connection.first, path,
475029573d4SEd Tanous                             "org.freedesktop.DBus.Properties", "GetAll",
4760fda0f12SGeorge Liu                             "xyz.openbmc_project.Inventory.Decorator.Asset");
477e4a4b9a9SJames Feist 
4781e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
4791e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
4801e1e598dSJonathan Doman                             path,
4811e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
4821e1e598dSJonathan Doman                             "AssetTag",
4831e1e598dSJonathan Doman                             "AssetTag",
484168e20c1SEd Tanous                             [aResp](const boost::system::error_code ec2,
4851e1e598dSJonathan Doman                                     const std::string& value) {
486cb13a392SEd Tanous                             if (ec2)
487e4a4b9a9SJames Feist                             {
488e4a4b9a9SJames Feist                                 // doesn't have to include this
489e4a4b9a9SJames Feist                                 // interface
490e4a4b9a9SJames Feist                                 return;
491e4a4b9a9SJames Feist                             }
492e4a4b9a9SJames Feist 
4931e1e598dSJonathan Doman                             aResp->res.jsonValue["AssetTag"] = value;
4941e1e598dSJonathan Doman                             });
495029573d4SEd Tanous                     }
496029573d4SEd Tanous                 }
497029573d4SEd Tanous             }
498c5b2abe0SLewanczyk, Dawid         }
499c5b2abe0SLewanczyk, Dawid         },
500c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
501c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
502c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5036617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
5046617338dSEd Tanous         std::array<const char*, 5>{
5056617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
5066617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
5076617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
5086617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
5096617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
5106617338dSEd Tanous         });
511c5b2abe0SLewanczyk, Dawid }
512c5b2abe0SLewanczyk, Dawid 
513c5b2abe0SLewanczyk, Dawid /**
514c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
515c5b2abe0SLewanczyk, Dawid  *
516c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
517c5b2abe0SLewanczyk, Dawid  *
518c5b2abe0SLewanczyk, Dawid  * @return None.
519c5b2abe0SLewanczyk, Dawid  */
5208d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5211abe55efSEd Tanous {
52255c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5231e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5241e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5251e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5261e1e598dSJonathan Doman         "CurrentHostState",
527c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
5281e1e598dSJonathan Doman                 const std::string& hostState) {
5291abe55efSEd Tanous         if (ec)
5301abe55efSEd Tanous         {
53122228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
53222228c28SAndrew Geissler             {
53322228c28SAndrew Geissler                 // Service not available, no error, just don't return
53422228c28SAndrew Geissler                 // host state info
53522228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
53622228c28SAndrew Geissler                 return;
53722228c28SAndrew Geissler             }
53822228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
539f12894f8SJason M. Bills             messages::internalError(aResp->res);
540c5b2abe0SLewanczyk, Dawid             return;
541c5b2abe0SLewanczyk, Dawid         }
5426617338dSEd Tanous 
5431e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
544c5b2abe0SLewanczyk, Dawid         // Verify Host State
5451e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5461abe55efSEd Tanous         {
54755c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "On";
5486617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Enabled";
5491abe55efSEd Tanous         }
5501e1e598dSJonathan Doman         else if (hostState ==
5510fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
5528c888608SGunnar Mills         {
5538c888608SGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
5548c888608SGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Quiesced";
5558c888608SGunnar Mills         }
5561e1e598dSJonathan Doman         else if (hostState ==
5570fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
55883935af9SAndrew Geissler         {
55983935af9SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "On";
56083935af9SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "InTest";
56183935af9SAndrew Geissler         }
5620fda0f12SGeorge Liu         else if (
5631e1e598dSJonathan Doman             hostState ==
5640fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5651a2a1437SAndrew Geissler         {
5661a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOn";
56715c27bf8SNoah Brewer             aResp->res.jsonValue["Status"]["State"] = "Starting";
5681a2a1437SAndrew Geissler         }
569002d39b4SEd Tanous         else if (hostState ==
5700fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5711a2a1437SAndrew Geissler         {
5721a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOff";
5731a2a1437SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "Disabled";
5741a2a1437SAndrew Geissler         }
5751abe55efSEd Tanous         else
5761abe55efSEd Tanous         {
57755c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "Off";
5786617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Disabled";
579c5b2abe0SLewanczyk, Dawid         }
5801e1e598dSJonathan Doman         });
581c5b2abe0SLewanczyk, Dawid }
582c5b2abe0SLewanczyk, Dawid 
583c5b2abe0SLewanczyk, Dawid /**
584786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
585491d8ee7SSantosh Puranik  *
586491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
587491d8ee7SSantosh Puranik  *
588491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
589491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
590491d8ee7SSantosh Puranik  */
59123a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
592491d8ee7SSantosh Puranik {
593491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
594491d8ee7SSantosh Puranik     {
595491d8ee7SSantosh Puranik         return "None";
596491d8ee7SSantosh Puranik     }
5973174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
598491d8ee7SSantosh Puranik     {
599491d8ee7SSantosh Puranik         return "Hdd";
600491d8ee7SSantosh Puranik     }
6013174e4dfSEd Tanous     if (dbusSource ==
602a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
603491d8ee7SSantosh Puranik     {
604491d8ee7SSantosh Puranik         return "Cd";
605491d8ee7SSantosh Puranik     }
6063174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
607491d8ee7SSantosh Puranik     {
608491d8ee7SSantosh Puranik         return "Pxe";
609491d8ee7SSantosh Puranik     }
6103174e4dfSEd Tanous     if (dbusSource ==
611944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6129f16b2c1SJennifer Lee     {
6139f16b2c1SJennifer Lee         return "Usb";
6149f16b2c1SJennifer Lee     }
615491d8ee7SSantosh Puranik     return "";
616491d8ee7SSantosh Puranik }
617491d8ee7SSantosh Puranik 
618491d8ee7SSantosh Puranik /**
619cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
620cd9a4666SKonstantin Aladyshev  *
621cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
622cd9a4666SKonstantin Aladyshev  *
623cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
624cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
625cd9a4666SKonstantin Aladyshev  */
626cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
627cd9a4666SKonstantin Aladyshev {
628cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
629cd9a4666SKonstantin Aladyshev     {
630cd9a4666SKonstantin Aladyshev         return "Legacy";
631cd9a4666SKonstantin Aladyshev     }
632cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
633cd9a4666SKonstantin Aladyshev     {
634cd9a4666SKonstantin Aladyshev         return "UEFI";
635cd9a4666SKonstantin Aladyshev     }
636cd9a4666SKonstantin Aladyshev     return "";
637cd9a4666SKonstantin Aladyshev }
638cd9a4666SKonstantin Aladyshev 
639cd9a4666SKonstantin Aladyshev /**
640786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
641491d8ee7SSantosh Puranik  *
642491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
643491d8ee7SSantosh Puranik  *
644491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
645491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
646491d8ee7SSantosh Puranik  */
64723a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
648491d8ee7SSantosh Puranik {
649491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
650491d8ee7SSantosh Puranik     {
651491d8ee7SSantosh Puranik         return "None";
652491d8ee7SSantosh Puranik     }
6533174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
654491d8ee7SSantosh Puranik     {
655491d8ee7SSantosh Puranik         return "Diags";
656491d8ee7SSantosh Puranik     }
6573174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
658491d8ee7SSantosh Puranik     {
659491d8ee7SSantosh Puranik         return "BiosSetup";
660491d8ee7SSantosh Puranik     }
661491d8ee7SSantosh Puranik     return "";
662491d8ee7SSantosh Puranik }
663491d8ee7SSantosh Puranik 
664491d8ee7SSantosh Puranik /**
665e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
666e43914b3SAndrew Geissler  *
667e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
668e43914b3SAndrew Geissler  *
669e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
670e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
671e43914b3SAndrew Geissler  */
672e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
673e43914b3SAndrew Geissler {
674e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
675e43914b3SAndrew Geissler     // enum
676e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
677e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
678e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
679e43914b3SAndrew Geissler     {
680e43914b3SAndrew Geissler         rfBpLastState = "None";
681e43914b3SAndrew Geissler     }
682e43914b3SAndrew Geissler     else if (dbusBootProgress ==
683e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
684e43914b3SAndrew Geissler              "PrimaryProcInit")
685e43914b3SAndrew Geissler     {
686e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
687e43914b3SAndrew Geissler     }
688e43914b3SAndrew Geissler     else if (dbusBootProgress ==
689e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
690e43914b3SAndrew Geissler              "BusInit")
691e43914b3SAndrew Geissler     {
692e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
693e43914b3SAndrew Geissler     }
694e43914b3SAndrew Geissler     else if (dbusBootProgress ==
695e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
696e43914b3SAndrew Geissler              "MemoryInit")
697e43914b3SAndrew Geissler     {
698e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
699e43914b3SAndrew Geissler     }
700e43914b3SAndrew Geissler     else if (dbusBootProgress ==
701e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
702e43914b3SAndrew Geissler              "SecondaryProcInit")
703e43914b3SAndrew Geissler     {
704e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
705e43914b3SAndrew Geissler     }
706e43914b3SAndrew Geissler     else if (dbusBootProgress ==
707e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
708e43914b3SAndrew Geissler              "PCIInit")
709e43914b3SAndrew Geissler     {
710e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
711e43914b3SAndrew Geissler     }
712e43914b3SAndrew Geissler     else if (dbusBootProgress ==
713e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
714e43914b3SAndrew Geissler              "SystemSetup")
715e43914b3SAndrew Geissler     {
716e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
717e43914b3SAndrew Geissler     }
718e43914b3SAndrew Geissler     else if (dbusBootProgress ==
719e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
720e43914b3SAndrew Geissler              "SystemInitComplete")
721e43914b3SAndrew Geissler     {
722e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
723e43914b3SAndrew Geissler     }
724e43914b3SAndrew Geissler     else if (dbusBootProgress ==
725e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
726e43914b3SAndrew Geissler              "OSStart")
727e43914b3SAndrew Geissler     {
728e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
729e43914b3SAndrew Geissler     }
730e43914b3SAndrew Geissler     else if (dbusBootProgress ==
731e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
732e43914b3SAndrew Geissler              "OSRunning")
733e43914b3SAndrew Geissler     {
734e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
735e43914b3SAndrew Geissler     }
736e43914b3SAndrew Geissler     else
737e43914b3SAndrew Geissler     {
738e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
739e43914b3SAndrew Geissler                          << dbusBootProgress;
740e43914b3SAndrew Geissler         // Just return the default
741e43914b3SAndrew Geissler     }
742e43914b3SAndrew Geissler     return rfBpLastState;
743e43914b3SAndrew Geissler }
744e43914b3SAndrew Geissler 
745e43914b3SAndrew Geissler /**
746786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
747491d8ee7SSantosh Puranik  *
748491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
749944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
750944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
751491d8ee7SSantosh Puranik  *
752944ffaf9SJohnathan Mantey  * @return Integer error code.
753491d8ee7SSantosh Puranik  */
7548d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
755944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
756944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
757491d8ee7SSantosh Puranik {
758c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
759c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
760944ffaf9SJohnathan Mantey 
761491d8ee7SSantosh Puranik     if (rfSource == "None")
762491d8ee7SSantosh Puranik     {
763944ffaf9SJohnathan Mantey         return 0;
764491d8ee7SSantosh Puranik     }
7653174e4dfSEd Tanous     if (rfSource == "Pxe")
766491d8ee7SSantosh Puranik     {
767944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
768944ffaf9SJohnathan Mantey     }
769944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
770944ffaf9SJohnathan Mantey     {
771944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
772944ffaf9SJohnathan Mantey     }
773944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
774944ffaf9SJohnathan Mantey     {
775944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
776944ffaf9SJohnathan Mantey     }
777944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
778944ffaf9SJohnathan Mantey     {
779944ffaf9SJohnathan Mantey         bootSource =
780944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
781944ffaf9SJohnathan Mantey     }
782944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
783944ffaf9SJohnathan Mantey     {
784944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
785491d8ee7SSantosh Puranik     }
7869f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7879f16b2c1SJennifer Lee     {
788944ffaf9SJohnathan Mantey         bootSource =
789944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
7909f16b2c1SJennifer Lee     }
791491d8ee7SSantosh Puranik     else
792491d8ee7SSantosh Puranik     {
7930fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
7940fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
795944ffaf9SJohnathan Mantey             << bootSource;
796944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
797944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
798944ffaf9SJohnathan Mantey         return -1;
799491d8ee7SSantosh Puranik     }
800944ffaf9SJohnathan Mantey     return 0;
801491d8ee7SSantosh Puranik }
8021981771bSAli Ahmed 
803978b8803SAndrew Geissler /**
804978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
805978b8803SAndrew Geissler  *
806978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
807978b8803SAndrew Geissler  *
808978b8803SAndrew Geissler  * @return None.
809978b8803SAndrew Geissler  */
8108d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
811978b8803SAndrew Geissler {
8121e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8131e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8141e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8151e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
816978b8803SAndrew Geissler         [aResp](const boost::system::error_code ec,
8171e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
818978b8803SAndrew Geissler         if (ec)
819978b8803SAndrew Geissler         {
820978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
821978b8803SAndrew Geissler             // not found
822978b8803SAndrew Geissler             return;
823978b8803SAndrew Geissler         }
824978b8803SAndrew Geissler 
8251e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
826978b8803SAndrew Geissler 
827e43914b3SAndrew Geissler         aResp->res.jsonValue["BootProgress"]["LastState"] =
828e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8291e1e598dSJonathan Doman         });
830978b8803SAndrew Geissler }
831491d8ee7SSantosh Puranik 
832491d8ee7SSantosh Puranik /**
833c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
834cd9a4666SKonstantin Aladyshev  *
835cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
836cd9a4666SKonstantin Aladyshev  *
837cd9a4666SKonstantin Aladyshev  * @return None.
838cd9a4666SKonstantin Aladyshev  */
839cd9a4666SKonstantin Aladyshev 
840c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
841cd9a4666SKonstantin Aladyshev {
8421e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8431e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
8441e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8451e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
846cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
8471e1e598dSJonathan Doman                 const std::string& bootType) {
848cd9a4666SKonstantin Aladyshev         if (ec)
849cd9a4666SKonstantin Aladyshev         {
850cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
851cd9a4666SKonstantin Aladyshev             return;
852cd9a4666SKonstantin Aladyshev         }
853cd9a4666SKonstantin Aladyshev 
8541e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
855cd9a4666SKonstantin Aladyshev 
856002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
857002d39b4SEd Tanous                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
858002d39b4SEd Tanous             {"Legacy", "UEFI"};
859cd9a4666SKonstantin Aladyshev 
8601e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
861cd9a4666SKonstantin Aladyshev         if (rfType.empty())
862cd9a4666SKonstantin Aladyshev         {
863cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
864cd9a4666SKonstantin Aladyshev             return;
865cd9a4666SKonstantin Aladyshev         }
866cd9a4666SKonstantin Aladyshev 
867cd9a4666SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
8681e1e598dSJonathan Doman         });
869cd9a4666SKonstantin Aladyshev }
870cd9a4666SKonstantin Aladyshev 
871cd9a4666SKonstantin Aladyshev /**
872c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
873491d8ee7SSantosh Puranik  *
874491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
875491d8ee7SSantosh Puranik  *
876491d8ee7SSantosh Puranik  * @return None.
877491d8ee7SSantosh Puranik  */
878c21865c4SKonstantin Aladyshev 
879c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
880491d8ee7SSantosh Puranik {
8811e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8821e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
8831e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8841e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
885c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
8861e1e598dSJonathan Doman                 const std::string& bootModeStr) {
887491d8ee7SSantosh Puranik         if (ec)
888491d8ee7SSantosh Puranik         {
889491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
890491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
891491d8ee7SSantosh Puranik             return;
892491d8ee7SSantosh Puranik         }
893491d8ee7SSantosh Puranik 
8941e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
895491d8ee7SSantosh Puranik 
8960fda0f12SGeorge Liu         aResp->res
8970fda0f12SGeorge Liu             .jsonValue["Boot"]
898002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
899002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
900491d8ee7SSantosh Puranik 
9011e1e598dSJonathan Doman         if (bootModeStr !=
902491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
903491d8ee7SSantosh Puranik         {
9041e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
905491d8ee7SSantosh Puranik             if (!rfMode.empty())
906491d8ee7SSantosh Puranik             {
907491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
908491d8ee7SSantosh Puranik                     rfMode;
909491d8ee7SSantosh Puranik             }
910491d8ee7SSantosh Puranik         }
9111e1e598dSJonathan Doman         });
912491d8ee7SSantosh Puranik }
913491d8ee7SSantosh Puranik 
914491d8ee7SSantosh Puranik /**
915c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
916491d8ee7SSantosh Puranik  *
917491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
918491d8ee7SSantosh Puranik  *
919491d8ee7SSantosh Puranik  * @return None.
920491d8ee7SSantosh Puranik  */
921c21865c4SKonstantin Aladyshev 
922c21865c4SKonstantin Aladyshev inline void
923c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
924491d8ee7SSantosh Puranik {
9251e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9261e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9271e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9281e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
929c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
9301e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
931491d8ee7SSantosh Puranik         if (ec)
932491d8ee7SSantosh Puranik         {
933491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
9345ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
9355ef735c8SNan Zhou             {
9365ef735c8SNan Zhou                 return;
9375ef735c8SNan Zhou             }
938491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
939491d8ee7SSantosh Puranik             return;
940491d8ee7SSantosh Puranik         }
941491d8ee7SSantosh Puranik 
9421e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
943491d8ee7SSantosh Puranik 
9441e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
945491d8ee7SSantosh Puranik         if (!rfSource.empty())
946491d8ee7SSantosh Puranik         {
947002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
948491d8ee7SSantosh Puranik         }
949cd9a4666SKonstantin Aladyshev 
950cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
951cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
952c21865c4SKonstantin Aladyshev         getBootOverrideMode(aResp);
9531e1e598dSJonathan Doman         });
954491d8ee7SSantosh Puranik }
955491d8ee7SSantosh Puranik 
956491d8ee7SSantosh Puranik /**
957c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
958c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
959c21865c4SKonstantin Aladyshev  * state
960491d8ee7SSantosh Puranik  *
961491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
962491d8ee7SSantosh Puranik  *
963491d8ee7SSantosh Puranik  * @return None.
964491d8ee7SSantosh Puranik  */
965491d8ee7SSantosh Puranik 
966c21865c4SKonstantin Aladyshev inline void
967c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
968c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
969c21865c4SKonstantin Aladyshev {
970c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
971c21865c4SKonstantin Aladyshev     {
972c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
973c21865c4SKonstantin Aladyshev         return;
974c21865c4SKonstantin Aladyshev     }
975c21865c4SKonstantin Aladyshev 
976c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
977c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
9781e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
9791e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9801e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
9811e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
9821e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
983491d8ee7SSantosh Puranik         if (ec)
984491d8ee7SSantosh Puranik         {
985491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
986c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
987491d8ee7SSantosh Puranik             return;
988491d8ee7SSantosh Puranik         }
989491d8ee7SSantosh Puranik 
990c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
991c21865c4SKonstantin Aladyshev         {
992002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
993c21865c4SKonstantin Aladyshev         }
994c21865c4SKonstantin Aladyshev         else
995c21865c4SKonstantin Aladyshev         {
996c21865c4SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
997c21865c4SKonstantin Aladyshev                 "Continuous";
998c21865c4SKonstantin Aladyshev         }
9991e1e598dSJonathan Doman         });
1000491d8ee7SSantosh Puranik }
1001491d8ee7SSantosh Puranik 
1002491d8ee7SSantosh Puranik /**
1003c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1004c21865c4SKonstantin Aladyshev  *
1005c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1006c21865c4SKonstantin Aladyshev  *
1007c21865c4SKonstantin Aladyshev  * @return None.
1008c21865c4SKonstantin Aladyshev  */
1009c21865c4SKonstantin Aladyshev 
1010c21865c4SKonstantin Aladyshev inline void
1011c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1012c21865c4SKonstantin Aladyshev {
10131e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10141e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10151e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10161e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1017c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
10181e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1019c21865c4SKonstantin Aladyshev         if (ec)
1020c21865c4SKonstantin Aladyshev         {
1021c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10225ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10235ef735c8SNan Zhou             {
10245ef735c8SNan Zhou                 return;
10255ef735c8SNan Zhou             }
1026c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1027c21865c4SKonstantin Aladyshev             return;
1028c21865c4SKonstantin Aladyshev         }
1029c21865c4SKonstantin Aladyshev 
10301e1e598dSJonathan Doman         processBootOverrideEnable(aResp, bootOverrideEnable);
10311e1e598dSJonathan Doman         });
1032c21865c4SKonstantin Aladyshev }
1033c21865c4SKonstantin Aladyshev 
1034c21865c4SKonstantin Aladyshev /**
1035c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1036c21865c4SKonstantin Aladyshev  *
1037c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1038c21865c4SKonstantin Aladyshev  *
1039c21865c4SKonstantin Aladyshev  * @return None.
1040c21865c4SKonstantin Aladyshev  */
1041c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1042c21865c4SKonstantin Aladyshev {
1043c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1044c21865c4SKonstantin Aladyshev 
1045c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1046c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1047c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1048c21865c4SKonstantin Aladyshev }
1049c21865c4SKonstantin Aladyshev 
1050c21865c4SKonstantin Aladyshev /**
1051c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1052c0557e1aSGunnar Mills  *
1053c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1054c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1055c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1056c0557e1aSGunnar Mills  * last power operation time.
1057c0557e1aSGunnar Mills  *
1058c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1059c0557e1aSGunnar Mills  *
1060c0557e1aSGunnar Mills  * @return None.
1061c0557e1aSGunnar Mills  */
10628d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1063c0557e1aSGunnar Mills {
1064c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1065c0557e1aSGunnar Mills 
10661e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
10671e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
10681e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
10691e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
10701e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
1071c0557e1aSGunnar Mills         if (ec)
1072c0557e1aSGunnar Mills         {
1073c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1074c0557e1aSGunnar Mills             return;
1075c0557e1aSGunnar Mills         }
1076c0557e1aSGunnar Mills 
1077c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1078c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
10791e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1080c0557e1aSGunnar Mills 
1081c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1082c0557e1aSGunnar Mills         aResp->res.jsonValue["LastResetTime"] =
1083*2b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
10841e1e598dSJonathan Doman         });
1085c0557e1aSGunnar Mills }
1086c0557e1aSGunnar Mills 
1087c0557e1aSGunnar Mills /**
10886bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
10896bd5a8d2SGunnar Mills  *
10906bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
10916bd5a8d2SGunnar Mills  *
10926bd5a8d2SGunnar Mills  * @return None.
10936bd5a8d2SGunnar Mills  */
10948d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
10956bd5a8d2SGunnar Mills {
10966bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
10976bd5a8d2SGunnar Mills 
10981e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10991e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11001e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
11011e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
11021e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
11036bd5a8d2SGunnar Mills         if (ec)
11046bd5a8d2SGunnar Mills         {
11056bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
11066bd5a8d2SGunnar Mills             return;
11076bd5a8d2SGunnar Mills         }
11086bd5a8d2SGunnar Mills 
11091e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1110e05aec50SEd Tanous         if (autoRebootEnabled)
11116bd5a8d2SGunnar Mills         {
11126bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11136bd5a8d2SGunnar Mills                 "RetryAttempts";
11146bd5a8d2SGunnar Mills             // If AutomaticRetry (AutoReboot) is enabled see how many
11156bd5a8d2SGunnar Mills             // attempts are left
11161e1e598dSJonathan Doman             sdbusplus::asio::getProperty<uint32_t>(
1117002d39b4SEd Tanous                 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
11181e1e598dSJonathan Doman                 "/xyz/openbmc_project/state/host0",
11191e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.Boot.RebootAttempts",
11201e1e598dSJonathan Doman                 "AttemptsLeft",
1121cb13a392SEd Tanous                 [aResp](const boost::system::error_code ec2,
1122914e2d5dSEd Tanous                         const uint32_t autoRebootAttemptsLeft) {
1123cb13a392SEd Tanous                 if (ec2)
11246bd5a8d2SGunnar Mills                 {
1125cb13a392SEd Tanous                     BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
11266bd5a8d2SGunnar Mills                     return;
11276bd5a8d2SGunnar Mills                 }
11286bd5a8d2SGunnar Mills 
11296bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
11301e1e598dSJonathan Doman                                  << autoRebootAttemptsLeft;
11316bd5a8d2SGunnar Mills 
11326bd5a8d2SGunnar Mills                 aResp->res
1133002d39b4SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
11341e1e598dSJonathan Doman                     autoRebootAttemptsLeft;
11351e1e598dSJonathan Doman                 });
11366bd5a8d2SGunnar Mills         }
11376bd5a8d2SGunnar Mills         else
11386bd5a8d2SGunnar Mills         {
1139002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
11406bd5a8d2SGunnar Mills         }
11416bd5a8d2SGunnar Mills 
11426bd5a8d2SGunnar Mills         // Not on D-Bus. Hardcoded here:
11436bd5a8d2SGunnar Mills         // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
11446bd5a8d2SGunnar Mills         aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
114569f35306SGunnar Mills 
114669f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
114769f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
114869f35306SGunnar Mills         // RetryAttempts.
1149002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
11500fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
11510fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
11521e1e598dSJonathan Doman         });
11536bd5a8d2SGunnar Mills }
11546bd5a8d2SGunnar Mills 
11556bd5a8d2SGunnar Mills /**
1156c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1157c6a620f2SGeorge Liu  *
1158c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1159c6a620f2SGeorge Liu  *
1160c6a620f2SGeorge Liu  * @return None.
1161c6a620f2SGeorge Liu  */
11628d1b46d7Szhanghch05 inline void
11638d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1164c6a620f2SGeorge Liu {
1165c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1166c6a620f2SGeorge Liu 
11671e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
11681e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11691e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
11701e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
11711e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, const std::string& policy) {
1172c6a620f2SGeorge Liu         if (ec)
1173c6a620f2SGeorge Liu         {
1174c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1175c6a620f2SGeorge Liu             return;
1176c6a620f2SGeorge Liu         }
1177c6a620f2SGeorge Liu 
11780fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
11790fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1180c6a620f2SGeorge Liu              "AlwaysOn"},
11810fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1182c6a620f2SGeorge Liu              "AlwaysOff"},
11830fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
11844ed47cb8SMatthew Barth              "LastState"},
11854ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
11864ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
11874ed47cb8SMatthew Barth              "AlwaysOff"}};
1188c6a620f2SGeorge Liu 
11891e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1190c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1191c6a620f2SGeorge Liu         {
1192c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1193c6a620f2SGeorge Liu             return;
1194c6a620f2SGeorge Liu         }
1195c6a620f2SGeorge Liu 
1196c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
11971e1e598dSJonathan Doman         });
1198c6a620f2SGeorge Liu }
1199c6a620f2SGeorge Liu 
1200c6a620f2SGeorge Liu /**
12011981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
12021981771bSAli Ahmed  * TPM is required for booting the host.
12031981771bSAli Ahmed  *
12041981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
12051981771bSAli Ahmed  *
12061981771bSAli Ahmed  * @return None.
12071981771bSAli Ahmed  */
12081981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
12091981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12101981771bSAli Ahmed {
12111981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
12121981771bSAli Ahmed 
12131981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
1214b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
1215b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
12161981771bSAli Ahmed         if (ec)
12171981771bSAli Ahmed         {
1218002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1219002d39b4SEd Tanous                              << ec;
12201981771bSAli Ahmed             // This is an optional D-Bus object so just return if
12211981771bSAli Ahmed             // error occurs
12221981771bSAli Ahmed             return;
12231981771bSAli Ahmed         }
122426f6976fSEd Tanous         if (subtree.empty())
12251981771bSAli Ahmed         {
12261981771bSAli Ahmed             // As noted above, this is an optional interface so just return
12271981771bSAli Ahmed             // if there is no instance found
12281981771bSAli Ahmed             return;
12291981771bSAli Ahmed         }
12301981771bSAli Ahmed 
12311981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
12321981771bSAli Ahmed         if (subtree.size() > 1)
12331981771bSAli Ahmed         {
12341981771bSAli Ahmed             BMCWEB_LOG_DEBUG
12351981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
12361981771bSAli Ahmed                 << subtree.size();
12371981771bSAli Ahmed             // Throw an internal Error and return
12381981771bSAli Ahmed             messages::internalError(aResp->res);
12391981771bSAli Ahmed             return;
12401981771bSAli Ahmed         }
12411981771bSAli Ahmed 
12421981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
12431981771bSAli Ahmed         // field
12441981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
12451981771bSAli Ahmed         {
12461981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
12471981771bSAli Ahmed             messages::internalError(aResp->res);
12481981771bSAli Ahmed             return;
12491981771bSAli Ahmed         }
12501981771bSAli Ahmed 
12511981771bSAli Ahmed         const std::string& path = subtree[0].first;
12521981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
12531981771bSAli Ahmed 
12541981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
12551e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
12561e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
12571e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
12588a592810SEd Tanous             [aResp](const boost::system::error_code ec2, bool tpmRequired) {
12598a592810SEd Tanous             if (ec2)
12601981771bSAli Ahmed             {
1261002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
12628a592810SEd Tanous                                  << ec2;
12631981771bSAli Ahmed                 messages::internalError(aResp->res);
12641981771bSAli Ahmed                 return;
12651981771bSAli Ahmed             }
12661981771bSAli Ahmed 
12671e1e598dSJonathan Doman             if (tpmRequired)
12681981771bSAli Ahmed             {
1269002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
12701981771bSAli Ahmed                     "Required";
12711981771bSAli Ahmed             }
12721981771bSAli Ahmed             else
12731981771bSAli Ahmed             {
1274002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
12751981771bSAli Ahmed                     "Disabled";
12761981771bSAli Ahmed             }
12771e1e598dSJonathan Doman             });
12781981771bSAli Ahmed         },
12791981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
12801981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
12811981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
12821981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
12831981771bSAli Ahmed }
12841981771bSAli Ahmed 
12851981771bSAli Ahmed /**
12861c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
12871c05dae3SAli Ahmed  * TPM is required for booting the host.
12881c05dae3SAli Ahmed  *
12891c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
12901c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
12911c05dae3SAli Ahmed  *
12921c05dae3SAli Ahmed  * @return None.
12931c05dae3SAli Ahmed  */
12941c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
12951c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
12961c05dae3SAli Ahmed {
12971c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
12981c05dae3SAli Ahmed 
12991c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
1300b9d36b47SEd Tanous         [aResp, tpmRequired](const boost::system::error_code ec,
1301b9d36b47SEd Tanous                              dbus::utility::MapperGetSubTreeResponse& subtree) {
13021c05dae3SAli Ahmed         if (ec)
13031c05dae3SAli Ahmed         {
1304002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1305002d39b4SEd Tanous                              << ec;
13061c05dae3SAli Ahmed             messages::internalError(aResp->res);
13071c05dae3SAli Ahmed             return;
13081c05dae3SAli Ahmed         }
130926f6976fSEd Tanous         if (subtree.empty())
13101c05dae3SAli Ahmed         {
13111c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
13121c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
13131c05dae3SAli Ahmed             return;
13141c05dae3SAli Ahmed         }
13151c05dae3SAli Ahmed 
13161c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
13171c05dae3SAli Ahmed         if (subtree.size() > 1)
13181c05dae3SAli Ahmed         {
13191c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
13201c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13211c05dae3SAli Ahmed                 << subtree.size();
13221c05dae3SAli Ahmed             // Throw an internal Error and return
13231c05dae3SAli Ahmed             messages::internalError(aResp->res);
13241c05dae3SAli Ahmed             return;
13251c05dae3SAli Ahmed         }
13261c05dae3SAli Ahmed 
13271c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13281c05dae3SAli Ahmed         // field
13291c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13301c05dae3SAli Ahmed         {
13311c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13321c05dae3SAli Ahmed             messages::internalError(aResp->res);
13331c05dae3SAli Ahmed             return;
13341c05dae3SAli Ahmed         }
13351c05dae3SAli Ahmed 
13361c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
13371c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
13381c05dae3SAli Ahmed 
13391c05dae3SAli Ahmed         if (serv.empty())
13401c05dae3SAli Ahmed         {
13411c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
13421c05dae3SAli Ahmed             messages::internalError(aResp->res);
13431c05dae3SAli Ahmed             return;
13441c05dae3SAli Ahmed         }
13451c05dae3SAli Ahmed 
13461c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
13471c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
13488a592810SEd Tanous             [aResp](const boost::system::error_code ec2) {
13498a592810SEd Tanous             if (ec2)
13501c05dae3SAli Ahmed             {
13510fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
13520fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
13538a592810SEd Tanous                     << ec2;
13541c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13551c05dae3SAli Ahmed                 return;
13561c05dae3SAli Ahmed             }
13571c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
13581c05dae3SAli Ahmed             },
13591c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
13601c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1361168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
13621c05dae3SAli Ahmed         },
13631c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
13641c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
13651c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
13661c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
13671c05dae3SAli Ahmed }
13681c05dae3SAli Ahmed 
13691c05dae3SAli Ahmed /**
1370491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1371491d8ee7SSantosh Puranik  *
1372491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1373cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1374cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1375cd9a4666SKonstantin Aladyshev  */
1376cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1377cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1378cd9a4666SKonstantin Aladyshev {
1379c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1380cd9a4666SKonstantin Aladyshev 
1381c21865c4SKonstantin Aladyshev     if (!bootType)
1382cd9a4666SKonstantin Aladyshev     {
1383c21865c4SKonstantin Aladyshev         return;
1384c21865c4SKonstantin Aladyshev     }
1385c21865c4SKonstantin Aladyshev 
1386cd9a4666SKonstantin Aladyshev     // Source target specified
1387cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1388cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1389cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1390cd9a4666SKonstantin Aladyshev     {
1391cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1392cd9a4666SKonstantin Aladyshev     }
1393cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1394cd9a4666SKonstantin Aladyshev     {
1395cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1396cd9a4666SKonstantin Aladyshev     }
1397cd9a4666SKonstantin Aladyshev     else
1398cd9a4666SKonstantin Aladyshev     {
1399cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1400cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1401cd9a4666SKonstantin Aladyshev                          << *bootType;
1402cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1403cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1404cd9a4666SKonstantin Aladyshev         return;
1405cd9a4666SKonstantin Aladyshev     }
1406cd9a4666SKonstantin Aladyshev 
1407cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1408cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1409cd9a4666SKonstantin Aladyshev 
1410cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1411c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1412cd9a4666SKonstantin Aladyshev         if (ec)
1413cd9a4666SKonstantin Aladyshev         {
1414cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1415cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1416cd9a4666SKonstantin Aladyshev             {
1417cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1418cd9a4666SKonstantin Aladyshev                 return;
1419cd9a4666SKonstantin Aladyshev             }
1420cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1421cd9a4666SKonstantin Aladyshev             return;
1422cd9a4666SKonstantin Aladyshev         }
1423cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1424cd9a4666SKonstantin Aladyshev         },
1425c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1426c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1427cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1428cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1429168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1430cd9a4666SKonstantin Aladyshev }
1431cd9a4666SKonstantin Aladyshev 
1432cd9a4666SKonstantin Aladyshev /**
1433cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1434cd9a4666SKonstantin Aladyshev  *
1435cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1436c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1437c21865c4SKonstantin Aladyshev  * @return Integer error code.
1438c21865c4SKonstantin Aladyshev  */
1439c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1440c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1441c21865c4SKonstantin Aladyshev {
1442c21865c4SKonstantin Aladyshev     if (!bootEnable)
1443c21865c4SKonstantin Aladyshev     {
1444c21865c4SKonstantin Aladyshev         return;
1445c21865c4SKonstantin Aladyshev     }
1446c21865c4SKonstantin Aladyshev     // Source target specified
1447c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1448c21865c4SKonstantin Aladyshev 
1449c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1450c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1451c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1452c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1453c21865c4SKonstantin Aladyshev     {
1454c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1455c21865c4SKonstantin Aladyshev     }
1456c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1457c21865c4SKonstantin Aladyshev     {
1458c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1459c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1460c21865c4SKonstantin Aladyshev     }
1461c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1462c21865c4SKonstantin Aladyshev     {
1463c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1464c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1465c21865c4SKonstantin Aladyshev     }
1466c21865c4SKonstantin Aladyshev     else
1467c21865c4SKonstantin Aladyshev     {
14680fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
14690fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1470c21865c4SKonstantin Aladyshev             << *bootEnable;
1471c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1472c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1473c21865c4SKonstantin Aladyshev         return;
1474c21865c4SKonstantin Aladyshev     }
1475c21865c4SKonstantin Aladyshev 
1476c21865c4SKonstantin Aladyshev     // Act on validated parameters
1477c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1478c21865c4SKonstantin Aladyshev 
1479c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
14808a592810SEd Tanous         [aResp](const boost::system::error_code ec2) {
14818a592810SEd Tanous         if (ec2)
1482c21865c4SKonstantin Aladyshev         {
14838a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1484c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1485c21865c4SKonstantin Aladyshev             return;
1486c21865c4SKonstantin Aladyshev         }
1487c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1488c21865c4SKonstantin Aladyshev         },
1489c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1490c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1491c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1492c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1493168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1494c21865c4SKonstantin Aladyshev 
1495c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1496c21865c4SKonstantin Aladyshev     {
1497c21865c4SKonstantin Aladyshev         return;
1498c21865c4SKonstantin Aladyshev     }
1499c21865c4SKonstantin Aladyshev 
1500c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1501c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1502c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1503c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1504c21865c4SKonstantin Aladyshev 
1505c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1506c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1507c21865c4SKonstantin Aladyshev         if (ec)
1508c21865c4SKonstantin Aladyshev         {
1509c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1510c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1511c21865c4SKonstantin Aladyshev             return;
1512c21865c4SKonstantin Aladyshev         }
1513c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1514c21865c4SKonstantin Aladyshev         },
1515c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1516c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1517c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1518c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1519168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1520c21865c4SKonstantin Aladyshev }
1521c21865c4SKonstantin Aladyshev 
1522c21865c4SKonstantin Aladyshev /**
1523c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1524c21865c4SKonstantin Aladyshev  *
1525c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1526491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1527491d8ee7SSantosh Puranik  *
1528265c1602SJohnathan Mantey  * @return Integer error code.
1529491d8ee7SSantosh Puranik  */
1530cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1531cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1532491d8ee7SSantosh Puranik {
1533c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1534c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1535944ffaf9SJohnathan Mantey 
1536c21865c4SKonstantin Aladyshev     if (!bootSource)
1537491d8ee7SSantosh Puranik     {
1538c21865c4SKonstantin Aladyshev         return;
1539c21865c4SKonstantin Aladyshev     }
1540c21865c4SKonstantin Aladyshev 
1541491d8ee7SSantosh Puranik     // Source target specified
1542491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1543491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1544e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1545e662eae8SEd Tanous         0)
1546491d8ee7SSantosh Puranik     {
1547944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1548944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1549491d8ee7SSantosh Puranik             << *bootSource;
1550491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1551491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1552491d8ee7SSantosh Puranik         return;
1553491d8ee7SSantosh Puranik     }
1554491d8ee7SSantosh Puranik 
1555944ffaf9SJohnathan Mantey     // Act on validated parameters
1556944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1557944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1558944ffaf9SJohnathan Mantey 
1559491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1560491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1561491d8ee7SSantosh Puranik         if (ec)
1562491d8ee7SSantosh Puranik         {
1563491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1564491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1565491d8ee7SSantosh Puranik             return;
1566491d8ee7SSantosh Puranik         }
1567491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1568491d8ee7SSantosh Puranik         },
1569c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1570c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1571491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1572491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1573168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1574944ffaf9SJohnathan Mantey 
1575491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1576491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1577491d8ee7SSantosh Puranik         if (ec)
1578491d8ee7SSantosh Puranik         {
1579491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1580491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1581491d8ee7SSantosh Puranik             return;
1582491d8ee7SSantosh Puranik         }
1583491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1584491d8ee7SSantosh Puranik         },
1585c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1586c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1587491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1588491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1589168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1590cd9a4666SKonstantin Aladyshev }
1591944ffaf9SJohnathan Mantey 
1592cd9a4666SKonstantin Aladyshev /**
1593c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1594491d8ee7SSantosh Puranik  *
1595491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1596491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1597cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1598491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1599491d8ee7SSantosh Puranik  *
1600265c1602SJohnathan Mantey  * @return Integer error code.
1601491d8ee7SSantosh Puranik  */
1602c21865c4SKonstantin Aladyshev 
1603c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1604c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1605c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1606c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1607491d8ee7SSantosh Puranik {
1608491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1609491d8ee7SSantosh Puranik 
1610c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1611c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1612c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1613491d8ee7SSantosh Puranik }
1614491d8ee7SSantosh Puranik 
1615c6a620f2SGeorge Liu /**
161698e386ecSGunnar Mills  * @brief Sets AssetTag
161798e386ecSGunnar Mills  *
161898e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
161998e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
162098e386ecSGunnar Mills  *
162198e386ecSGunnar Mills  * @return None.
162298e386ecSGunnar Mills  */
16238d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
162498e386ecSGunnar Mills                         const std::string& assetTag)
162598e386ecSGunnar Mills {
162698e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
1627b9d36b47SEd Tanous         [aResp,
1628b9d36b47SEd Tanous          assetTag](const boost::system::error_code ec,
1629b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
163098e386ecSGunnar Mills         if (ec)
163198e386ecSGunnar Mills         {
163298e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
163398e386ecSGunnar Mills             messages::internalError(aResp->res);
163498e386ecSGunnar Mills             return;
163598e386ecSGunnar Mills         }
163626f6976fSEd Tanous         if (subtree.empty())
163798e386ecSGunnar Mills         {
163898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
163998e386ecSGunnar Mills             messages::internalError(aResp->res);
164098e386ecSGunnar Mills             return;
164198e386ecSGunnar Mills         }
164298e386ecSGunnar Mills         // Assume only 1 system D-Bus object
164398e386ecSGunnar Mills         // Throw an error if there is more than 1
164498e386ecSGunnar Mills         if (subtree.size() > 1)
164598e386ecSGunnar Mills         {
164698e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
164798e386ecSGunnar Mills             messages::internalError(aResp->res);
164898e386ecSGunnar Mills             return;
164998e386ecSGunnar Mills         }
165098e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
165198e386ecSGunnar Mills         {
165298e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
165398e386ecSGunnar Mills             messages::internalError(aResp->res);
165498e386ecSGunnar Mills             return;
165598e386ecSGunnar Mills         }
165698e386ecSGunnar Mills 
165798e386ecSGunnar Mills         const std::string& path = subtree[0].first;
165898e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
165998e386ecSGunnar Mills 
166098e386ecSGunnar Mills         if (service.empty())
166198e386ecSGunnar Mills         {
166298e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
166398e386ecSGunnar Mills             messages::internalError(aResp->res);
166498e386ecSGunnar Mills             return;
166598e386ecSGunnar Mills         }
166698e386ecSGunnar Mills 
166798e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
166898e386ecSGunnar Mills             [aResp](const boost::system::error_code ec2) {
166998e386ecSGunnar Mills             if (ec2)
167098e386ecSGunnar Mills             {
1671002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1672002d39b4SEd Tanous                                  << ec2;
167398e386ecSGunnar Mills                 messages::internalError(aResp->res);
167498e386ecSGunnar Mills                 return;
167598e386ecSGunnar Mills             }
167698e386ecSGunnar Mills             },
167798e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
167898e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1679168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
168098e386ecSGunnar Mills         },
168198e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
168298e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
168398e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
168498e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
168598e386ecSGunnar Mills         std::array<const char*, 1>{
168698e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
168798e386ecSGunnar Mills }
168898e386ecSGunnar Mills 
168998e386ecSGunnar Mills /**
169069f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
169169f35306SGunnar Mills  *
169269f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
169369f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
169469f35306SGunnar Mills  *
169569f35306SGunnar Mills  * @return None.
169669f35306SGunnar Mills  */
16978d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1698f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
169969f35306SGunnar Mills {
170069f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
170169f35306SGunnar Mills 
170269f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1703543f4400SEd Tanous     bool autoRebootEnabled = false;
170469f35306SGunnar Mills 
170569f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
170669f35306SGunnar Mills     {
170769f35306SGunnar Mills         autoRebootEnabled = false;
170869f35306SGunnar Mills     }
170969f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
171069f35306SGunnar Mills     {
171169f35306SGunnar Mills         autoRebootEnabled = true;
171269f35306SGunnar Mills     }
171369f35306SGunnar Mills     else
171469f35306SGunnar Mills     {
17150fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
171669f35306SGunnar Mills                          << automaticRetryConfig;
171769f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
171869f35306SGunnar Mills                                          "AutomaticRetryConfig");
171969f35306SGunnar Mills         return;
172069f35306SGunnar Mills     }
172169f35306SGunnar Mills 
172269f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
172369f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
172469f35306SGunnar Mills         if (ec)
172569f35306SGunnar Mills         {
172669f35306SGunnar Mills             messages::internalError(aResp->res);
172769f35306SGunnar Mills             return;
172869f35306SGunnar Mills         }
172969f35306SGunnar Mills         },
173069f35306SGunnar Mills         "xyz.openbmc_project.Settings",
173169f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
173269f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
173369f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1734168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
173569f35306SGunnar Mills }
173669f35306SGunnar Mills 
173769f35306SGunnar Mills /**
1738c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1739c6a620f2SGeorge Liu  *
1740c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1741c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1742c6a620f2SGeorge Liu  *
1743c6a620f2SGeorge Liu  * @return None.
1744c6a620f2SGeorge Liu  */
17458d1b46d7Szhanghch05 inline void
17468d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
17474e69c904SGunnar Mills                           const std::string& policy)
1748c6a620f2SGeorge Liu {
1749c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1750c6a620f2SGeorge Liu 
1751c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
17520fda0f12SGeorge Liu         {"AlwaysOn",
17530fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
17540fda0f12SGeorge Liu         {"AlwaysOff",
17550fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
17560fda0f12SGeorge Liu         {"LastState",
17570fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1758c6a620f2SGeorge Liu 
1759c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1760c6a620f2SGeorge Liu 
17614e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1762c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1763c6a620f2SGeorge Liu     {
17644e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
17654e69c904SGunnar Mills                                          "PowerRestorePolicy");
1766c6a620f2SGeorge Liu         return;
1767c6a620f2SGeorge Liu     }
1768c6a620f2SGeorge Liu 
1769c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1770c6a620f2SGeorge Liu 
1771c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1772c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1773c6a620f2SGeorge Liu         if (ec)
1774c6a620f2SGeorge Liu         {
1775c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1776c6a620f2SGeorge Liu             return;
1777c6a620f2SGeorge Liu         }
1778c6a620f2SGeorge Liu         },
1779c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1780c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1781c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1782c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1783168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1784c6a620f2SGeorge Liu }
1785c6a620f2SGeorge Liu 
1786a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1787a6349918SAppaRao Puli /**
1788a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1789a6349918SAppaRao Puli  *
1790a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1791a6349918SAppaRao Puli  *
1792a6349918SAppaRao Puli  * @return None.
1793a6349918SAppaRao Puli  */
17948d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1795a6349918SAppaRao Puli {
1796a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1797a6349918SAppaRao Puli     crow::connections::systemBus->async_method_call(
1798a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
1799b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1800b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1801b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
180250626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
180350626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
180450626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
180550626f4fSJames Feist 
1806a6349918SAppaRao Puli         if (ec)
1807a6349918SAppaRao Puli         {
1808a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1809b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1810b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1811a6349918SAppaRao Puli             return;
1812a6349918SAppaRao Puli         }
1813a6349918SAppaRao Puli 
1814a6349918SAppaRao Puli         const bool* provState = nullptr;
1815a6349918SAppaRao Puli         const bool* lockState = nullptr;
18166e3b67ecSAppaRao Puli         for (const std::pair<std::string, dbus::utility::DbusVariantType>&
18176e3b67ecSAppaRao Puli                  property : propertiesList)
1818a6349918SAppaRao Puli         {
1819a6349918SAppaRao Puli             if (property.first == "UfmProvisioned")
1820a6349918SAppaRao Puli             {
1821a6349918SAppaRao Puli                 provState = std::get_if<bool>(&property.second);
1822a6349918SAppaRao Puli             }
1823a6349918SAppaRao Puli             else if (property.first == "UfmLocked")
1824a6349918SAppaRao Puli             {
1825a6349918SAppaRao Puli                 lockState = std::get_if<bool>(&property.second);
1826a6349918SAppaRao Puli             }
1827a6349918SAppaRao Puli         }
1828a6349918SAppaRao Puli 
1829a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1830a6349918SAppaRao Puli         {
1831a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1832a6349918SAppaRao Puli             messages::internalError(aResp->res);
1833a6349918SAppaRao Puli             return;
1834a6349918SAppaRao Puli         }
1835a6349918SAppaRao Puli 
1836a6349918SAppaRao Puli         if (*provState == true)
1837a6349918SAppaRao Puli         {
1838a6349918SAppaRao Puli             if (*lockState == true)
1839a6349918SAppaRao Puli             {
1840a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1841a6349918SAppaRao Puli             }
1842a6349918SAppaRao Puli             else
1843a6349918SAppaRao Puli             {
1844a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1845a6349918SAppaRao Puli             }
1846a6349918SAppaRao Puli         }
1847a6349918SAppaRao Puli         else
1848a6349918SAppaRao Puli         {
1849a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1850a6349918SAppaRao Puli         }
1851a6349918SAppaRao Puli         },
1852a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1853a6349918SAppaRao Puli         "org.freedesktop.DBus.Properties", "GetAll",
1854a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Attributes");
1855a6349918SAppaRao Puli }
1856a6349918SAppaRao Puli #endif
1857a6349918SAppaRao Puli 
1858491d8ee7SSantosh Puranik /**
18593a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
18603a2d0424SChris Cain  *
18613a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
18623a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
18633a2d0424SChris Cain  *
18643a2d0424SChris Cain  * @return None.
18653a2d0424SChris Cain  */
18663a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18673a2d0424SChris Cain                                const std::string& modeValue)
18683a2d0424SChris Cain {
18690fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
18703a2d0424SChris Cain     {
18713a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
18723a2d0424SChris Cain     }
18730fda0f12SGeorge Liu     else if (
18740fda0f12SGeorge Liu         modeValue ==
18750fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
18763a2d0424SChris Cain     {
18773a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
18783a2d0424SChris Cain     }
18790fda0f12SGeorge Liu     else if (modeValue ==
18800fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
18813a2d0424SChris Cain     {
18823a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
18833a2d0424SChris Cain     }
18840fda0f12SGeorge Liu     else if (modeValue ==
18850fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
18863a2d0424SChris Cain     {
18873a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
18883a2d0424SChris Cain     }
18893a2d0424SChris Cain     else
18903a2d0424SChris Cain     {
18913a2d0424SChris Cain         // Any other values would be invalid
18923a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
18933a2d0424SChris Cain         messages::internalError(aResp->res);
18943a2d0424SChris Cain     }
18953a2d0424SChris Cain }
18963a2d0424SChris Cain 
18973a2d0424SChris Cain /**
18983a2d0424SChris Cain  * @brief Retrieves system power mode
18993a2d0424SChris Cain  *
19003a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19013a2d0424SChris Cain  *
19023a2d0424SChris Cain  * @return None.
19033a2d0424SChris Cain  */
19043a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
19053a2d0424SChris Cain {
19063a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
19073a2d0424SChris Cain 
19083a2d0424SChris Cain     // Get Power Mode object path:
19093a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
1910b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
1911b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
19123a2d0424SChris Cain         if (ec)
19133a2d0424SChris Cain         {
1914002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1915002d39b4SEd Tanous                              << ec;
19163a2d0424SChris Cain             // This is an optional D-Bus object so just return if
19173a2d0424SChris Cain             // error occurs
19183a2d0424SChris Cain             return;
19193a2d0424SChris Cain         }
19203a2d0424SChris Cain         if (subtree.empty())
19213a2d0424SChris Cain         {
19223a2d0424SChris Cain             // As noted above, this is an optional interface so just return
19233a2d0424SChris Cain             // if there is no instance found
19243a2d0424SChris Cain             return;
19253a2d0424SChris Cain         }
19263a2d0424SChris Cain         if (subtree.size() > 1)
19273a2d0424SChris Cain         {
19283a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
19293a2d0424SChris Cain             // error
19303a2d0424SChris Cain             BMCWEB_LOG_DEBUG
19313a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
19323a2d0424SChris Cain                 << subtree.size();
19333a2d0424SChris Cain             messages::internalError(aResp->res);
19343a2d0424SChris Cain             return;
19353a2d0424SChris Cain         }
19363a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
19373a2d0424SChris Cain         {
19383a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
19393a2d0424SChris Cain             messages::internalError(aResp->res);
19403a2d0424SChris Cain             return;
19413a2d0424SChris Cain         }
19423a2d0424SChris Cain         const std::string& path = subtree[0].first;
19433a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
19443a2d0424SChris Cain         if (service.empty())
19453a2d0424SChris Cain         {
19463a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
19473a2d0424SChris Cain             messages::internalError(aResp->res);
19483a2d0424SChris Cain             return;
19493a2d0424SChris Cain         }
19503a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
19511e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
19521e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
19531e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
19548a592810SEd Tanous             [aResp](const boost::system::error_code ec2,
19551e1e598dSJonathan Doman                     const std::string& pmode) {
19568a592810SEd Tanous             if (ec2)
19573a2d0424SChris Cain             {
1958002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
19598a592810SEd Tanous                                  << ec2;
19603a2d0424SChris Cain                 messages::internalError(aResp->res);
19613a2d0424SChris Cain                 return;
19623a2d0424SChris Cain             }
19633a2d0424SChris Cain 
1964002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
1965002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
19663a2d0424SChris Cain 
19671e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
19681e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
19691e1e598dSJonathan Doman             });
19703a2d0424SChris Cain         },
19713a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
19723a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
19733a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
19743a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
19753a2d0424SChris Cain }
19763a2d0424SChris Cain 
19773a2d0424SChris Cain /**
19783a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
19793a2d0424SChris Cain  * name associated with that string
19803a2d0424SChris Cain  *
19813a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
19823a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
19833a2d0424SChris Cain  *
19843a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
19853a2d0424SChris Cain  */
19863a2d0424SChris Cain inline std::string
19873a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19883a2d0424SChris Cain                       const std::string& modeString)
19893a2d0424SChris Cain {
19903a2d0424SChris Cain     std::string mode;
19913a2d0424SChris Cain 
19923a2d0424SChris Cain     if (modeString == "Static")
19933a2d0424SChris Cain     {
19943a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
19953a2d0424SChris Cain     }
19963a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
19973a2d0424SChris Cain     {
19980fda0f12SGeorge Liu         mode =
19990fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
20003a2d0424SChris Cain     }
20013a2d0424SChris Cain     else if (modeString == "PowerSaving")
20023a2d0424SChris Cain     {
20033a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
20043a2d0424SChris Cain     }
20053a2d0424SChris Cain     else
20063a2d0424SChris Cain     {
20073a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
20083a2d0424SChris Cain     }
20093a2d0424SChris Cain     return mode;
20103a2d0424SChris Cain }
20113a2d0424SChris Cain 
20123a2d0424SChris Cain /**
20133a2d0424SChris Cain  * @brief Sets system power mode.
20143a2d0424SChris Cain  *
20153a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20163a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
20173a2d0424SChris Cain  *
20183a2d0424SChris Cain  * @return None.
20193a2d0424SChris Cain  */
20203a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20213a2d0424SChris Cain                          const std::string& pmode)
20223a2d0424SChris Cain {
20233a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
20243a2d0424SChris Cain 
20253a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
20263a2d0424SChris Cain     if (powerMode.empty())
20273a2d0424SChris Cain     {
20283a2d0424SChris Cain         return;
20293a2d0424SChris Cain     }
20303a2d0424SChris Cain 
20313a2d0424SChris Cain     // Get Power Mode object path:
20323a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
2033b9d36b47SEd Tanous         [aResp,
2034b9d36b47SEd Tanous          powerMode](const boost::system::error_code ec,
2035b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
20363a2d0424SChris Cain         if (ec)
20373a2d0424SChris Cain         {
2038002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2039002d39b4SEd Tanous                              << ec;
20403a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
20413a2d0424SChris Cain             messages::internalError(aResp->res);
20423a2d0424SChris Cain             return;
20433a2d0424SChris Cain         }
20443a2d0424SChris Cain         if (subtree.empty())
20453a2d0424SChris Cain         {
20463a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
20473a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
20483a2d0424SChris Cain                                        "PowerMode");
20493a2d0424SChris Cain             return;
20503a2d0424SChris Cain         }
20513a2d0424SChris Cain         if (subtree.size() > 1)
20523a2d0424SChris Cain         {
20533a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
20543a2d0424SChris Cain             // error
20553a2d0424SChris Cain             BMCWEB_LOG_DEBUG
20563a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
20573a2d0424SChris Cain                 << subtree.size();
20583a2d0424SChris Cain             messages::internalError(aResp->res);
20593a2d0424SChris Cain             return;
20603a2d0424SChris Cain         }
20613a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
20623a2d0424SChris Cain         {
20633a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
20643a2d0424SChris Cain             messages::internalError(aResp->res);
20653a2d0424SChris Cain             return;
20663a2d0424SChris Cain         }
20673a2d0424SChris Cain         const std::string& path = subtree[0].first;
20683a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
20693a2d0424SChris Cain         if (service.empty())
20703a2d0424SChris Cain         {
20713a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20723a2d0424SChris Cain             messages::internalError(aResp->res);
20733a2d0424SChris Cain             return;
20743a2d0424SChris Cain         }
20753a2d0424SChris Cain 
20763a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
20773a2d0424SChris Cain                          << path;
20783a2d0424SChris Cain 
20793a2d0424SChris Cain         // Set the Power Mode property
20803a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
20818a592810SEd Tanous             [aResp](const boost::system::error_code ec2) {
20828a592810SEd Tanous             if (ec2)
20833a2d0424SChris Cain             {
20843a2d0424SChris Cain                 messages::internalError(aResp->res);
20853a2d0424SChris Cain                 return;
20863a2d0424SChris Cain             }
20873a2d0424SChris Cain             },
20883a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
20893a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2090168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
20913a2d0424SChris Cain         },
20923a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
20933a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
20943a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
20953a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
20963a2d0424SChris Cain }
20973a2d0424SChris Cain 
20983a2d0424SChris Cain /**
209951709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
210051709ffdSYong Li  *
210151709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
210251709ffdSYong Li  *
210351709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
210451709ffdSYong Li  * translation cannot be done, returns an empty string.
210551709ffdSYong Li  */
210623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
210751709ffdSYong Li {
210851709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
210951709ffdSYong Li     {
211051709ffdSYong Li         return "None";
211151709ffdSYong Li     }
21123174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
211351709ffdSYong Li     {
211451709ffdSYong Li         return "ResetSystem";
211551709ffdSYong Li     }
21163174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
211751709ffdSYong Li     {
211851709ffdSYong Li         return "PowerDown";
211951709ffdSYong Li     }
21203174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
212151709ffdSYong Li     {
212251709ffdSYong Li         return "PowerCycle";
212351709ffdSYong Li     }
212451709ffdSYong Li 
212551709ffdSYong Li     return "";
212651709ffdSYong Li }
212751709ffdSYong Li 
212851709ffdSYong Li /**
2129c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2130c45f0082SYong Li  *
2131c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2132c45f0082SYong Li  *
2133c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2134c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2135c45f0082SYong Li  */
2136c45f0082SYong Li 
213723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2138c45f0082SYong Li {
2139c45f0082SYong Li     if (rfAction == "None")
2140c45f0082SYong Li     {
2141c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2142c45f0082SYong Li     }
21433174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2144c45f0082SYong Li     {
2145c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2146c45f0082SYong Li     }
21473174e4dfSEd Tanous     if (rfAction == "PowerDown")
2148c45f0082SYong Li     {
2149c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2150c45f0082SYong Li     }
21513174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2152c45f0082SYong Li     {
2153c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2154c45f0082SYong Li     }
2155c45f0082SYong Li 
2156c45f0082SYong Li     return "";
2157c45f0082SYong Li }
2158c45f0082SYong Li 
2159c45f0082SYong Li /**
216051709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
216151709ffdSYong Li  *
216251709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
216351709ffdSYong Li  *
216451709ffdSYong Li  * @return None.
216551709ffdSYong Li  */
21668d1b46d7Szhanghch05 inline void
21678d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
216851709ffdSYong Li {
216951709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
217051709ffdSYong Li     crow::connections::systemBus->async_method_call(
217151709ffdSYong Li         [aResp](const boost::system::error_code ec,
2172b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
217351709ffdSYong Li         if (ec)
217451709ffdSYong Li         {
217551709ffdSYong Li             // watchdog service is stopped
217651709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
217751709ffdSYong Li             return;
217851709ffdSYong Li         }
217951709ffdSYong Li 
218051709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
218151709ffdSYong Li 
218251709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
218351709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
218451709ffdSYong Li 
218551709ffdSYong Li         // watchdog service is running/enabled
218651709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
218751709ffdSYong Li 
218851709ffdSYong Li         for (const auto& property : properties)
218951709ffdSYong Li         {
219051709ffdSYong Li             BMCWEB_LOG_DEBUG << "prop=" << property.first;
219151709ffdSYong Li             if (property.first == "Enabled")
219251709ffdSYong Li             {
219351709ffdSYong Li                 const bool* state = std::get_if<bool>(&property.second);
219451709ffdSYong Li 
2195e662eae8SEd Tanous                 if (state == nullptr)
219651709ffdSYong Li                 {
219751709ffdSYong Li                     messages::internalError(aResp->res);
2198601af5edSChicago Duan                     return;
219951709ffdSYong Li                 }
220051709ffdSYong Li 
220151709ffdSYong Li                 hostWatchdogTimer["FunctionEnabled"] = *state;
220251709ffdSYong Li             }
220351709ffdSYong Li             else if (property.first == "ExpireAction")
220451709ffdSYong Li             {
220551709ffdSYong Li                 const std::string* s =
220651709ffdSYong Li                     std::get_if<std::string>(&property.second);
2207e662eae8SEd Tanous                 if (s == nullptr)
220851709ffdSYong Li                 {
220951709ffdSYong Li                     messages::internalError(aResp->res);
2210601af5edSChicago Duan                     return;
221151709ffdSYong Li                 }
221251709ffdSYong Li 
221351709ffdSYong Li                 std::string action = dbusToRfWatchdogAction(*s);
221451709ffdSYong Li                 if (action.empty())
221551709ffdSYong Li                 {
221651709ffdSYong Li                     messages::internalError(aResp->res);
2217601af5edSChicago Duan                     return;
221851709ffdSYong Li                 }
221951709ffdSYong Li                 hostWatchdogTimer["TimeoutAction"] = action;
222051709ffdSYong Li             }
222151709ffdSYong Li         }
222251709ffdSYong Li         },
222351709ffdSYong Li         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
222451709ffdSYong Li         "org.freedesktop.DBus.Properties", "GetAll",
222551709ffdSYong Li         "xyz.openbmc_project.State.Watchdog");
222651709ffdSYong Li }
222751709ffdSYong Li 
222851709ffdSYong Li /**
2229c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2230c45f0082SYong Li  *
2231c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2232c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2233c45f0082SYong Li  *                       RF request.
2234c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2235c45f0082SYong Li  *
2236c45f0082SYong Li  * @return None.
2237c45f0082SYong Li  */
22388d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2239c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2240c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2241c45f0082SYong Li {
2242c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2243c45f0082SYong Li 
2244c45f0082SYong Li     if (wdtTimeOutAction)
2245c45f0082SYong Li     {
2246c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2247c45f0082SYong Li         // check if TimeOut Action is Valid
2248c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2249c45f0082SYong Li         {
2250c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2251c45f0082SYong Li                              << *wdtTimeOutAction;
2252c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2253c45f0082SYong Li                                              "TimeoutAction");
2254c45f0082SYong Li             return;
2255c45f0082SYong Li         }
2256c45f0082SYong Li 
2257c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2258c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2259c45f0082SYong Li             if (ec)
2260c45f0082SYong Li             {
2261c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2262c45f0082SYong Li                 messages::internalError(aResp->res);
2263c45f0082SYong Li                 return;
2264c45f0082SYong Li             }
2265c45f0082SYong Li             },
2266c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2267c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2268c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2269c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2270168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2271c45f0082SYong Li     }
2272c45f0082SYong Li 
2273c45f0082SYong Li     if (wdtEnable)
2274c45f0082SYong Li     {
2275c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2276c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2277c45f0082SYong Li             if (ec)
2278c45f0082SYong Li             {
2279c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2280c45f0082SYong Li                 messages::internalError(aResp->res);
2281c45f0082SYong Li                 return;
2282c45f0082SYong Li             }
2283c45f0082SYong Li             },
2284c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2285c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2286c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2287c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2288168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2289c45f0082SYong Li     }
2290c45f0082SYong Li }
2291c45f0082SYong Li 
229237bbf98cSChris Cain /**
229337bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
229437bbf98cSChris Cain  *
229537bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
229637bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
229737bbf98cSChris Cain  *
229837bbf98cSChris Cain  * @return true if successful
229937bbf98cSChris Cain  */
23001e5b7c88SJiaqing Zhao inline bool
23011e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
23021e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
230337bbf98cSChris Cain {
230437bbf98cSChris Cain     for (const auto& property : properties)
230537bbf98cSChris Cain     {
230637bbf98cSChris Cain         if (property.first == "Enabled")
230737bbf98cSChris Cain         {
230837bbf98cSChris Cain             const bool* state = std::get_if<bool>(&property.second);
2309e662eae8SEd Tanous             if (state == nullptr)
231037bbf98cSChris Cain             {
231137bbf98cSChris Cain                 return false;
231237bbf98cSChris Cain             }
231337bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *state;
231437bbf98cSChris Cain         }
231537bbf98cSChris Cain         else if (property.first == "EnterUtilizationPercent")
231637bbf98cSChris Cain         {
231737bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
2318e662eae8SEd Tanous             if (util == nullptr)
231937bbf98cSChris Cain             {
232037bbf98cSChris Cain                 return false;
232137bbf98cSChris Cain             }
232237bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
232337bbf98cSChris Cain         }
232437bbf98cSChris Cain         else if (property.first == "EnterDwellTime")
232537bbf98cSChris Cain         {
232637bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
232737bbf98cSChris Cain             const uint64_t* timeMilliseconds =
232837bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
2329e662eae8SEd Tanous             if (timeMilliseconds == nullptr)
233037bbf98cSChris Cain             {
233137bbf98cSChris Cain                 return false;
233237bbf98cSChris Cain             }
233337bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
233437bbf98cSChris Cain                 *timeMilliseconds);
233537bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
233637bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
233737bbf98cSChris Cain                     .count();
233837bbf98cSChris Cain         }
233937bbf98cSChris Cain         else if (property.first == "ExitUtilizationPercent")
234037bbf98cSChris Cain         {
234137bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
2342e662eae8SEd Tanous             if (util == nullptr)
234337bbf98cSChris Cain             {
234437bbf98cSChris Cain                 return false;
234537bbf98cSChris Cain             }
234637bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
234737bbf98cSChris Cain         }
234837bbf98cSChris Cain         else if (property.first == "ExitDwellTime")
234937bbf98cSChris Cain         {
235037bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
235137bbf98cSChris Cain             const uint64_t* timeMilliseconds =
235237bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
2353e662eae8SEd Tanous             if (timeMilliseconds == nullptr)
235437bbf98cSChris Cain             {
235537bbf98cSChris Cain                 return false;
235637bbf98cSChris Cain             }
235737bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
235837bbf98cSChris Cain                 *timeMilliseconds);
235937bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
236037bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
236137bbf98cSChris Cain                     .count();
236237bbf98cSChris Cain         }
236337bbf98cSChris Cain         else
236437bbf98cSChris Cain         {
236537bbf98cSChris Cain             BMCWEB_LOG_WARNING << "Unexpected IdlePowerSaver property: "
236637bbf98cSChris Cain                                << property.first;
236737bbf98cSChris Cain         }
236837bbf98cSChris Cain     }
236937bbf98cSChris Cain 
237037bbf98cSChris Cain     return true;
237137bbf98cSChris Cain }
237237bbf98cSChris Cain 
237337bbf98cSChris Cain /**
237437bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
237537bbf98cSChris Cain  *
237637bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
237737bbf98cSChris Cain  *
237837bbf98cSChris Cain  * @return None.
237937bbf98cSChris Cain  */
238037bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
238137bbf98cSChris Cain {
238237bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
238337bbf98cSChris Cain 
238437bbf98cSChris Cain     // Get IdlePowerSaver object path:
238537bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
2386b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
2387b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
238837bbf98cSChris Cain         if (ec)
238937bbf98cSChris Cain         {
239037bbf98cSChris Cain             BMCWEB_LOG_DEBUG
239137bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
239237bbf98cSChris Cain                 << ec;
239337bbf98cSChris Cain             messages::internalError(aResp->res);
239437bbf98cSChris Cain             return;
239537bbf98cSChris Cain         }
239637bbf98cSChris Cain         if (subtree.empty())
239737bbf98cSChris Cain         {
239837bbf98cSChris Cain             // This is an optional interface so just return
239937bbf98cSChris Cain             // if there is no instance found
240037bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
240137bbf98cSChris Cain             return;
240237bbf98cSChris Cain         }
240337bbf98cSChris Cain         if (subtree.size() > 1)
240437bbf98cSChris Cain         {
240537bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
240637bbf98cSChris Cain             // is an error
240737bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
240837bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
240937bbf98cSChris Cain                              << subtree.size();
241037bbf98cSChris Cain             messages::internalError(aResp->res);
241137bbf98cSChris Cain             return;
241237bbf98cSChris Cain         }
241337bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
241437bbf98cSChris Cain         {
241537bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
241637bbf98cSChris Cain             messages::internalError(aResp->res);
241737bbf98cSChris Cain             return;
241837bbf98cSChris Cain         }
241937bbf98cSChris Cain         const std::string& path = subtree[0].first;
242037bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
242137bbf98cSChris Cain         if (service.empty())
242237bbf98cSChris Cain         {
2423002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
242437bbf98cSChris Cain             messages::internalError(aResp->res);
242537bbf98cSChris Cain             return;
242637bbf98cSChris Cain         }
242737bbf98cSChris Cain 
242837bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
242937bbf98cSChris Cain         crow::connections::systemBus->async_method_call(
24308a592810SEd Tanous             [aResp](const boost::system::error_code ec2,
24311e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
24328a592810SEd Tanous             if (ec2)
243337bbf98cSChris Cain             {
243437bbf98cSChris Cain                 BMCWEB_LOG_ERROR
24358a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
243637bbf98cSChris Cain                 messages::internalError(aResp->res);
243737bbf98cSChris Cain                 return;
243837bbf98cSChris Cain             }
243937bbf98cSChris Cain 
2440e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
244137bbf98cSChris Cain             {
244237bbf98cSChris Cain                 messages::internalError(aResp->res);
244337bbf98cSChris Cain                 return;
244437bbf98cSChris Cain             }
244537bbf98cSChris Cain             },
244637bbf98cSChris Cain             service, path, "org.freedesktop.DBus.Properties", "GetAll",
244737bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver");
244837bbf98cSChris Cain         },
244937bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
245037bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
245137bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
245237bbf98cSChris Cain         std::array<const char*, 1>{
245337bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
245437bbf98cSChris Cain 
245537bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
245637bbf98cSChris Cain }
245737bbf98cSChris Cain 
245837bbf98cSChris Cain /**
245937bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
246037bbf98cSChris Cain  *
246137bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
246237bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
246337bbf98cSChris Cain  *                       RF request.
246437bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
246537bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
246637bbf98cSChris Cain  * before entering idle state.
246737bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
246837bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
246937bbf98cSChris Cain  * before exiting idle state
247037bbf98cSChris Cain  *
247137bbf98cSChris Cain  * @return None.
247237bbf98cSChris Cain  */
247337bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
247437bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
247537bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
247637bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
247737bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
247837bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
247937bbf98cSChris Cain {
248037bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
248137bbf98cSChris Cain 
248237bbf98cSChris Cain     // Get IdlePowerSaver object path:
248337bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
248437bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2485b9d36b47SEd Tanous          ipsExitTime](const boost::system::error_code ec,
2486b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
248737bbf98cSChris Cain         if (ec)
248837bbf98cSChris Cain         {
248937bbf98cSChris Cain             BMCWEB_LOG_DEBUG
249037bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
249137bbf98cSChris Cain                 << ec;
249237bbf98cSChris Cain             messages::internalError(aResp->res);
249337bbf98cSChris Cain             return;
249437bbf98cSChris Cain         }
249537bbf98cSChris Cain         if (subtree.empty())
249637bbf98cSChris Cain         {
249737bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
249837bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
249937bbf98cSChris Cain                                        "IdlePowerSaver");
250037bbf98cSChris Cain             return;
250137bbf98cSChris Cain         }
250237bbf98cSChris Cain         if (subtree.size() > 1)
250337bbf98cSChris Cain         {
250437bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
250537bbf98cSChris Cain             // is an error
25060fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
25070fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
250837bbf98cSChris Cain                 << subtree.size();
250937bbf98cSChris Cain             messages::internalError(aResp->res);
251037bbf98cSChris Cain             return;
251137bbf98cSChris Cain         }
251237bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
251337bbf98cSChris Cain         {
251437bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
251537bbf98cSChris Cain             messages::internalError(aResp->res);
251637bbf98cSChris Cain             return;
251737bbf98cSChris Cain         }
251837bbf98cSChris Cain         const std::string& path = subtree[0].first;
251937bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
252037bbf98cSChris Cain         if (service.empty())
252137bbf98cSChris Cain         {
2522002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
252337bbf98cSChris Cain             messages::internalError(aResp->res);
252437bbf98cSChris Cain             return;
252537bbf98cSChris Cain         }
252637bbf98cSChris Cain 
252737bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
252837bbf98cSChris Cain         // need to be updated
252937bbf98cSChris Cain 
253037bbf98cSChris Cain         if (ipsEnable)
253137bbf98cSChris Cain         {
253237bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25338a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25348a592810SEd Tanous                 if (ec2)
253537bbf98cSChris Cain                 {
25368a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
253737bbf98cSChris Cain                     messages::internalError(aResp->res);
253837bbf98cSChris Cain                     return;
253937bbf98cSChris Cain                 }
254037bbf98cSChris Cain                 },
254137bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2542002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2543002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
254437bbf98cSChris Cain         }
254537bbf98cSChris Cain         if (ipsEnterUtil)
254637bbf98cSChris Cain         {
254737bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25488a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25498a592810SEd Tanous                 if (ec2)
255037bbf98cSChris Cain                 {
25518a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
255237bbf98cSChris Cain                     messages::internalError(aResp->res);
255337bbf98cSChris Cain                     return;
255437bbf98cSChris Cain                 }
255537bbf98cSChris Cain                 },
255637bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
255737bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
255837bbf98cSChris Cain                 "EnterUtilizationPercent",
2559168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
256037bbf98cSChris Cain         }
256137bbf98cSChris Cain         if (ipsEnterTime)
256237bbf98cSChris Cain         {
256337bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
256437bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
256537bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25668a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25678a592810SEd Tanous                 if (ec2)
256837bbf98cSChris Cain                 {
25698a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
257037bbf98cSChris Cain                     messages::internalError(aResp->res);
257137bbf98cSChris Cain                     return;
257237bbf98cSChris Cain                 }
257337bbf98cSChris Cain                 },
257437bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
257537bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2576168e20c1SEd Tanous                 "EnterDwellTime",
2577168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
257837bbf98cSChris Cain         }
257937bbf98cSChris Cain         if (ipsExitUtil)
258037bbf98cSChris Cain         {
258137bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25828a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25838a592810SEd Tanous                 if (ec2)
258437bbf98cSChris Cain                 {
25858a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
258637bbf98cSChris Cain                     messages::internalError(aResp->res);
258737bbf98cSChris Cain                     return;
258837bbf98cSChris Cain                 }
258937bbf98cSChris Cain                 },
259037bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
259137bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
259237bbf98cSChris Cain                 "ExitUtilizationPercent",
2593168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
259437bbf98cSChris Cain         }
259537bbf98cSChris Cain         if (ipsExitTime)
259637bbf98cSChris Cain         {
259737bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
259837bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
259937bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26008a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
26018a592810SEd Tanous                 if (ec2)
260237bbf98cSChris Cain                 {
26038a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
260437bbf98cSChris Cain                     messages::internalError(aResp->res);
260537bbf98cSChris Cain                     return;
260637bbf98cSChris Cain                 }
260737bbf98cSChris Cain                 },
260837bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
260937bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2610168e20c1SEd Tanous                 "ExitDwellTime",
2611168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
261237bbf98cSChris Cain         }
261337bbf98cSChris Cain         },
261437bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
261537bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
261637bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
261737bbf98cSChris Cain         std::array<const char*, 1>{
261837bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
261937bbf98cSChris Cain 
262037bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
262137bbf98cSChris Cain }
262237bbf98cSChris Cain 
2623c45f0082SYong Li /**
2624c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2625c5b2abe0SLewanczyk, Dawid  * Schema
2626c5b2abe0SLewanczyk, Dawid  */
26277e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
26281abe55efSEd Tanous {
26297e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2630ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
26317e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2632f4c99e70SEd Tanous             [&app](const crow::Request& req,
26337e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
26343ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2635f4c99e70SEd Tanous         {
2636f4c99e70SEd Tanous             return;
2637f4c99e70SEd Tanous         }
26388d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
26390f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
26408d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
26418d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2642462023adSSunitha Harish 
26431e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2644002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
26451e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2646002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
26478a592810SEd Tanous             [asyncResp](const boost::system::error_code ec2,
26481e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2649002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
26502c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2651002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
26521476687dSEd Tanous 
26531476687dSEd Tanous             nlohmann::json::object_t system;
26541476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
26551476687dSEd Tanous             ifaceArray.push_back(std::move(system));
265694bda602STim Lee             count = ifaceArray.size();
26578a592810SEd Tanous             if (!ec2)
2658462023adSSunitha Harish             {
2659462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
26601476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2661002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
26621476687dSEd Tanous                 ifaceArray.push_back(std::move(hypervisor));
26632c70f800SEd Tanous                 count = ifaceArray.size();
2664cb13a392SEd Tanous             }
26651e1e598dSJonathan Doman             });
26667e860f15SJohn Edward Broadbent         });
2667c5b2abe0SLewanczyk, Dawid }
26687e860f15SJohn Edward Broadbent 
26697e860f15SJohn Edward Broadbent /**
26707e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
26717e860f15SJohn Edward Broadbent  */
26724f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
26737e860f15SJohn Edward Broadbent {
26747e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
26757e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
26767e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
26777e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
26787e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
26797e860f15SJohn Edward Broadbent 
26807e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
26817e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
26827e860f15SJohn Edward Broadbent         if (ec)
26837e860f15SJohn Edward Broadbent         {
26847e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
26857e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
26867e860f15SJohn Edward Broadbent             return;
26877e860f15SJohn Edward Broadbent         }
26887e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
26897e860f15SJohn Edward Broadbent         },
26907e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
26917e860f15SJohn Edward Broadbent }
2692c5b2abe0SLewanczyk, Dawid 
2693c5b2abe0SLewanczyk, Dawid /**
2694cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2695cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2696cc340dd9SEd Tanous  */
26977e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2698cc340dd9SEd Tanous {
2699cc340dd9SEd Tanous     /**
2700cc340dd9SEd Tanous      * Function handles POST method request.
2701cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2702cc340dd9SEd Tanous      */
27037e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
27047e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2705ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2706002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2707002d39b4SEd Tanous             [&app](const crow::Request& req,
27087e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27093ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
271045ca1b86SEd Tanous         {
271145ca1b86SEd Tanous             return;
271245ca1b86SEd Tanous         }
27139712f8acSEd Tanous         std::string resetType;
271415ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
27157e860f15SJohn Edward Broadbent                                        resetType))
2716cc340dd9SEd Tanous         {
2717cc340dd9SEd Tanous             return;
2718cc340dd9SEd Tanous         }
2719cc340dd9SEd Tanous 
2720d22c8396SJason M. Bills         // Get the command and host vs. chassis
2721cc340dd9SEd Tanous         std::string command;
2722543f4400SEd Tanous         bool hostCommand = true;
2723d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2724cc340dd9SEd Tanous         {
2725cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2726d22c8396SJason M. Bills             hostCommand = true;
2727d22c8396SJason M. Bills         }
2728d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2729d22c8396SJason M. Bills         {
2730d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2731d22c8396SJason M. Bills             hostCommand = false;
2732d22c8396SJason M. Bills         }
2733d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2734d22c8396SJason M. Bills         {
273586a0851aSJason M. Bills             command =
273686a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
273786a0851aSJason M. Bills             hostCommand = true;
2738cc340dd9SEd Tanous         }
27399712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2740cc340dd9SEd Tanous         {
2741cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2742d22c8396SJason M. Bills             hostCommand = true;
2743cc340dd9SEd Tanous         }
27449712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2745cc340dd9SEd Tanous         {
27460fda0f12SGeorge Liu             command =
27470fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2748d22c8396SJason M. Bills             hostCommand = true;
2749d22c8396SJason M. Bills         }
2750d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2751d22c8396SJason M. Bills         {
275286a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
275386a0851aSJason M. Bills             hostCommand = true;
2754cc340dd9SEd Tanous         }
2755bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2756bfd5b826SLakshminarayana R. Kammath         {
2757bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2758bfd5b826SLakshminarayana R. Kammath             return;
2759bfd5b826SLakshminarayana R. Kammath         }
2760cc340dd9SEd Tanous         else
2761cc340dd9SEd Tanous         {
27628d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
27638d1b46d7Szhanghch05                                              resetType);
2764cc340dd9SEd Tanous             return;
2765cc340dd9SEd Tanous         }
2766cc340dd9SEd Tanous 
2767d22c8396SJason M. Bills         if (hostCommand)
2768d22c8396SJason M. Bills         {
2769cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
2770d22c8396SJason M. Bills                 [asyncResp, resetType](const boost::system::error_code ec) {
2771cc340dd9SEd Tanous                 if (ec)
2772cc340dd9SEd Tanous                 {
2773cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2774002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2775d22c8396SJason M. Bills                     {
2776d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2777d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2778d22c8396SJason M. Bills                     }
2779d22c8396SJason M. Bills                     else
2780d22c8396SJason M. Bills                     {
2781f12894f8SJason M. Bills                         messages::internalError(asyncResp->res);
2782d22c8396SJason M. Bills                     }
2783cc340dd9SEd Tanous                     return;
2784cc340dd9SEd Tanous                 }
2785f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2786cc340dd9SEd Tanous                 },
2787cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2788cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2789cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
27909712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2791168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2792cc340dd9SEd Tanous         }
2793d22c8396SJason M. Bills         else
2794d22c8396SJason M. Bills         {
2795d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
2796d22c8396SJason M. Bills                 [asyncResp, resetType](const boost::system::error_code ec) {
2797d22c8396SJason M. Bills                 if (ec)
2798d22c8396SJason M. Bills                 {
2799d22c8396SJason M. Bills                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2800002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2801d22c8396SJason M. Bills                     {
2802d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2803d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2804d22c8396SJason M. Bills                     }
2805d22c8396SJason M. Bills                     else
2806d22c8396SJason M. Bills                     {
2807d22c8396SJason M. Bills                         messages::internalError(asyncResp->res);
2808d22c8396SJason M. Bills                     }
2809d22c8396SJason M. Bills                     return;
2810d22c8396SJason M. Bills                 }
2811d22c8396SJason M. Bills                 messages::success(asyncResp->res);
2812d22c8396SJason M. Bills                 },
2813d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
2814d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
2815d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
2816002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2817168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2818d22c8396SJason M. Bills         }
28197e860f15SJohn Edward Broadbent         });
2820d22c8396SJason M. Bills }
2821cc340dd9SEd Tanous 
2822cc340dd9SEd Tanous /**
28236617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2824c5b2abe0SLewanczyk, Dawid  */
28257e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
28261abe55efSEd Tanous {
2827c5b2abe0SLewanczyk, Dawid 
2828c5b2abe0SLewanczyk, Dawid     /**
2829c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2830c5b2abe0SLewanczyk, Dawid      */
28317e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2832ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
2833002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
2834002d39b4SEd Tanous             [&app](const crow::Request& req,
2835002d39b4SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28363ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
283745ca1b86SEd Tanous         {
283845ca1b86SEd Tanous             return;
283945ca1b86SEd Tanous         }
28408d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
284137bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
28428d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
28438d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
28448d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
28458d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
28468d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
28478d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
28488d1b46d7Szhanghch05             "Disabled";
28498d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
28508d1b46d7Szhanghch05             uint64_t(0);
28518d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
28528d1b46d7Szhanghch05             "Disabled";
2853002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
285404a258f4SEd Tanous 
28551476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
28561476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
28571476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
28581476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
28591476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
28601476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
2861029573d4SEd Tanous 
2862002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
28631476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
28641476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
28651476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
28661476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
2867c5b2abe0SLewanczyk, Dawid 
28681476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
28691476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
28701476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
28711476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
2872c4bf6374SJason M. Bills 
28731476687dSEd Tanous         nlohmann::json::array_t managedBy;
28741476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
28751476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
2876002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
28771476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
28781476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
28790e8ac5e7SGunnar Mills 
28800e8ac5e7SGunnar Mills         // Fill in SerialConsole info
2881002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
2882002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
2883002d39b4SEd Tanous             true;
28841476687dSEd Tanous 
28850e8ac5e7SGunnar Mills         // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
28861476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
28871476687dSEd Tanous             true;
28881476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
28891476687dSEd Tanous         asyncResp->res
28901476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
28911476687dSEd Tanous             "Press ~. to exit console";
28920e8ac5e7SGunnar Mills 
28930e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
28940e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
2895002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
2896002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
2897002d39b4SEd Tanous             4;
28981476687dSEd Tanous         asyncResp->res
2899002d39b4SEd Tanous             .jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = {"KVMIP"};
29001476687dSEd Tanous 
29010e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
2902e284a7c1SJames Feist         constexpr const std::array<const char*, 4> inventoryForSystems = {
2903b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
29042ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
2905e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
2906e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
2907b49ac873SJames Feist 
2908b49ac873SJames Feist         auto health = std::make_shared<HealthPopulate>(asyncResp);
2909b49ac873SJames Feist         crow::connections::systemBus->async_method_call(
2910b49ac873SJames Feist             [health](const boost::system::error_code ec,
2911914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
2912b49ac873SJames Feist             if (ec)
2913b49ac873SJames Feist             {
2914b49ac873SJames Feist                 // no inventory
2915b49ac873SJames Feist                 return;
2916b49ac873SJames Feist             }
2917b49ac873SJames Feist 
2918914e2d5dSEd Tanous             health->inventory = resp;
2919b49ac873SJames Feist             },
2920b49ac873SJames Feist             "xyz.openbmc_project.ObjectMapper",
2921b49ac873SJames Feist             "/xyz/openbmc_project/object_mapper",
2922b49ac873SJames Feist             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2923b49ac873SJames Feist             int32_t(0), inventoryForSystems);
2924b49ac873SJames Feist 
2925b49ac873SJames Feist         health->populate();
2926b49ac873SJames Feist 
2927002d39b4SEd Tanous         getMainChassisId(asyncResp,
2928002d39b4SEd Tanous                          [](const std::string& chassisId,
29298d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2930b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
2931b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
2932b2c7e208SEd Tanous             chassis["@odata.id"] = "/redfish/v1/Chassis/" + chassisId;
2933002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
2934c5d03ff4SJennifer Lee         });
2935a3002228SAppaRao Puli 
29369f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
29379f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
2938a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
29395bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
29406c34de48SEd Tanous         getHostState(asyncResp);
2941491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
2942978b8803SAndrew Geissler         getBootProgress(asyncResp);
2943adbe192aSJason M. Bills         getPCIeDeviceList(asyncResp, "PCIeDevices");
294451709ffdSYong Li         getHostWatchdogTimer(asyncResp);
2945c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
29466bd5a8d2SGunnar Mills         getAutomaticRetry(asyncResp);
2947c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
2948a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2949a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
2950a6349918SAppaRao Puli #endif
29511981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
29523a2d0424SChris Cain         getPowerMode(asyncResp);
295337bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
29547e860f15SJohn Edward Broadbent         });
2955550a6bf8SJiaqing Zhao 
29567e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2957ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
29587e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
295945ca1b86SEd Tanous             [&app](const crow::Request& req,
29607e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
29613ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
296245ca1b86SEd Tanous         {
296345ca1b86SEd Tanous             return;
296445ca1b86SEd Tanous         }
29659f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
2966cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
296798e386ecSGunnar Mills         std::optional<std::string> assetTag;
2968c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
29693a2d0424SChris Cain         std::optional<std::string> powerMode;
2970550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
2971550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
2972550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
2973550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
2974550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
2975550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
2976550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
2977550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
2978550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
2979550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
2980550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
2981550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
2982550a6bf8SJiaqing Zhao 
2983550a6bf8SJiaqing Zhao         // clang-format off
298415ed6780SWilly Tu         if (!json_util::readJsonPatch(
2985550a6bf8SJiaqing Zhao                 req, asyncResp->res,
2986550a6bf8SJiaqing Zhao                 "IndicatorLED", indicatorLed,
29877e860f15SJohn Edward Broadbent                 "LocationIndicatorActive", locationIndicatorActive,
2988550a6bf8SJiaqing Zhao                 "AssetTag", assetTag,
2989550a6bf8SJiaqing Zhao                 "PowerRestorePolicy", powerRestorePolicy,
2990550a6bf8SJiaqing Zhao                 "PowerMode", powerMode,
2991550a6bf8SJiaqing Zhao                 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
2992550a6bf8SJiaqing Zhao                 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
2993550a6bf8SJiaqing Zhao                 "Boot/BootSourceOverrideTarget", bootSource,
2994550a6bf8SJiaqing Zhao                 "Boot/BootSourceOverrideMode", bootType,
2995550a6bf8SJiaqing Zhao                 "Boot/BootSourceOverrideEnabled", bootEnable,
2996550a6bf8SJiaqing Zhao                 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
2997550a6bf8SJiaqing Zhao                 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
2998550a6bf8SJiaqing Zhao                 "IdlePowerSaver/Enabled", ipsEnable,
2999550a6bf8SJiaqing Zhao                 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3000550a6bf8SJiaqing Zhao                 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3001550a6bf8SJiaqing Zhao                 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3002550a6bf8SJiaqing Zhao                 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
30036617338dSEd Tanous         {
30046617338dSEd Tanous             return;
30056617338dSEd Tanous         }
3006550a6bf8SJiaqing Zhao         // clang-format on
3007491d8ee7SSantosh Puranik 
30088d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3009c45f0082SYong Li 
301098e386ecSGunnar Mills         if (assetTag)
301198e386ecSGunnar Mills         {
301298e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
301398e386ecSGunnar Mills         }
301498e386ecSGunnar Mills 
3015550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3016c45f0082SYong Li         {
3017f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3018c45f0082SYong Li         }
3019c45f0082SYong Li 
3020cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
302169f35306SGunnar Mills         {
3022002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3023491d8ee7SSantosh Puranik         }
3024550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
302569f35306SGunnar Mills         {
3026550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
302769f35306SGunnar Mills         }
3028ac7e1e0bSAli Ahmed 
3029550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3030ac7e1e0bSAli Ahmed         {
3031550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3032550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
303369f35306SGunnar Mills         }
3034265c1602SJohnathan Mantey 
30359f8bfa7cSGunnar Mills         if (locationIndicatorActive)
30369f8bfa7cSGunnar Mills         {
3037002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
30389f8bfa7cSGunnar Mills         }
30399f8bfa7cSGunnar Mills 
30407e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
30417e860f15SJohn Edward Broadbent         // passed
30429712f8acSEd Tanous         if (indicatorLed)
30436617338dSEd Tanous         {
3044f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3045002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3046d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3047d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
30486617338dSEd Tanous         }
3049c6a620f2SGeorge Liu 
3050c6a620f2SGeorge Liu         if (powerRestorePolicy)
3051c6a620f2SGeorge Liu         {
30524e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3053c6a620f2SGeorge Liu         }
30543a2d0424SChris Cain 
30553a2d0424SChris Cain         if (powerMode)
30563a2d0424SChris Cain         {
30573a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
30583a2d0424SChris Cain         }
305937bbf98cSChris Cain 
3060550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3061550a6bf8SJiaqing Zhao             ipsExitTime)
306237bbf98cSChris Cain         {
3063002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3064002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
306537bbf98cSChris Cain         }
30667e860f15SJohn Edward Broadbent         });
3067c5b2abe0SLewanczyk, Dawid }
30681cb1a9e6SAppaRao Puli 
30691cb1a9e6SAppaRao Puli /**
30701cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
30711cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
30721cb1a9e6SAppaRao Puli  */
30737e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
30741cb1a9e6SAppaRao Puli {
30751cb1a9e6SAppaRao Puli     /**
30761cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
30771cb1a9e6SAppaRao Puli      */
30787e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3079ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
30807e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
308145ca1b86SEd Tanous             [&app](const crow::Request& req,
30827e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
30833ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
308445ca1b86SEd Tanous         {
308545ca1b86SEd Tanous             return;
308645ca1b86SEd Tanous         }
30871476687dSEd Tanous 
30881476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
30891476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
30901476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
30911476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
30921476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
30931476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
30943215e700SNan Zhou 
30953215e700SNan Zhou         nlohmann::json::array_t parameters;
30963215e700SNan Zhou         nlohmann::json::object_t parameter;
30973215e700SNan Zhou 
30983215e700SNan Zhou         parameter["Name"] = "ResetType";
30993215e700SNan Zhou         parameter["Required"] = true;
31003215e700SNan Zhou         parameter["DataType"] = "String";
31013215e700SNan Zhou         nlohmann::json::array_t allowableValues;
31023215e700SNan Zhou         allowableValues.emplace_back("On");
31033215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
31043215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
31053215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
31063215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
31073215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
31083215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
31093215e700SNan Zhou         allowableValues.emplace_back("Nmi");
31103215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
31113215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
31123215e700SNan Zhou 
31133215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
31147e860f15SJohn Edward Broadbent         });
31151cb1a9e6SAppaRao Puli }
3116c5b2abe0SLewanczyk, Dawid } // namespace redfish
3117