xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 2661b72c84fc0c04b4d0acc7bca2e5a4d05cfaea)
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 
183ccb3adbSEd Tanous #include "app.hpp"
191e1e598dSJonathan Doman #include "dbus_singleton.hpp"
207a1dbc48SGeorge Liu #include "dbus_utility.hpp"
21b49ac873SJames Feist #include "health.hpp"
22746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
231c8fba97SJames Feist #include "led.hpp"
24f5c9f8bdSJason M. Bills #include "pcie.hpp"
25f4c99e70SEd Tanous #include "query.hpp"
26c5d03ff4SJennifer Lee #include "redfish_util.hpp"
273ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
283ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
293ccb3adbSEd Tanous #include "utils/json_utils.hpp"
303ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
312b82937eSEd Tanous #include "utils/time_utils.hpp"
32c5d03ff4SJennifer Lee 
339712f8acSEd Tanous #include <boost/container/flat_map.hpp>
34e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
351e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
36bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
371214b7e7SGunnar Mills 
387a1dbc48SGeorge Liu #include <array>
397a1dbc48SGeorge Liu #include <string_view>
40abf2add6SEd Tanous #include <variant>
41c5b2abe0SLewanczyk, Dawid 
421abe55efSEd Tanous namespace redfish
431abe55efSEd Tanous {
44c5b2abe0SLewanczyk, Dawid 
455c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
465c3e9272SAbhishek Patel     protocolToDBusForSystems{
475c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
485c3e9272SAbhishek Patel 
499d3ae10eSAlpana Kumari /**
509d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
519d3ae10eSAlpana Kumari  *
529d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
539d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
549d3ae10eSAlpana Kumari  *
559d3ae10eSAlpana Kumari  * @return None.
569d3ae10eSAlpana Kumari  */
578d1b46d7Szhanghch05 inline void
588d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
591e1e598dSJonathan Doman                          bool isDimmFunctional)
609d3ae10eSAlpana Kumari {
611e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
629d3ae10eSAlpana Kumari 
639d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
649d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
659d3ae10eSAlpana Kumari     // ENABLED.
6602cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
679d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
689d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
699d3ae10eSAlpana Kumari     {
70e05aec50SEd Tanous         if (isDimmFunctional)
719d3ae10eSAlpana Kumari         {
729d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
739d3ae10eSAlpana Kumari                 "Enabled";
749d3ae10eSAlpana Kumari         }
759d3ae10eSAlpana Kumari     }
769d3ae10eSAlpana Kumari }
779d3ae10eSAlpana Kumari 
7857e8c9beSAlpana Kumari /*
7957e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
8057e8c9beSAlpana Kumari  *
8157e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
8257e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
8357e8c9beSAlpana Kumari  *
8457e8c9beSAlpana Kumari  * @return None.
8557e8c9beSAlpana Kumari  */
861e1e598dSJonathan Doman inline void
871e1e598dSJonathan Doman     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
881e1e598dSJonathan Doman                            bool isCpuPresent)
8957e8c9beSAlpana Kumari {
901e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
9157e8c9beSAlpana Kumari 
9255f79e6fSEd Tanous     if (isCpuPresent)
9357e8c9beSAlpana Kumari     {
94b4b9595aSJames Feist         nlohmann::json& procCount =
95b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
9655f79e6fSEd Tanous         auto* procCountPtr =
97b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
98b4b9595aSJames Feist         if (procCountPtr != nullptr)
99b4b9595aSJames Feist         {
100b4b9595aSJames Feist             // shouldn't be possible to be nullptr
101b4b9595aSJames Feist             *procCountPtr += 1;
10257e8c9beSAlpana Kumari         }
103b4b9595aSJames Feist     }
10457e8c9beSAlpana Kumari }
10557e8c9beSAlpana Kumari 
10657e8c9beSAlpana Kumari /*
10757e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
10857e8c9beSAlpana Kumari  *        CPU Functional State
10957e8c9beSAlpana Kumari  *
11057e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
11157e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
11257e8c9beSAlpana Kumari  *
11357e8c9beSAlpana Kumari  * @return None.
11457e8c9beSAlpana Kumari  */
1151e1e598dSJonathan Doman inline void
1161e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1171e1e598dSJonathan Doman                              bool isCpuFunctional)
11857e8c9beSAlpana Kumari {
1191e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
12057e8c9beSAlpana Kumari 
12102cad96eSEd Tanous     const nlohmann::json& prevProcState =
12257e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
12357e8c9beSAlpana Kumari 
12457e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
12557e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
12657e8c9beSAlpana Kumari     // Functional.
12757e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
12857e8c9beSAlpana Kumari     {
129e05aec50SEd Tanous         if (isCpuFunctional)
13057e8c9beSAlpana Kumari         {
13157e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
13257e8c9beSAlpana Kumari                 "Enabled";
13357e8c9beSAlpana Kumari         }
13457e8c9beSAlpana Kumari     }
13557e8c9beSAlpana Kumari }
13657e8c9beSAlpana Kumari 
137382d6475SAli Ahmed inline void getProcessorProperties(
138382d6475SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
139382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
140382d6475SAli Ahmed         properties)
14103fbed92SAli Ahmed {
14203fbed92SAli Ahmed 
14303fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
14403fbed92SAli Ahmed 
14503fbed92SAli Ahmed     // TODO: Get Model
14603fbed92SAli Ahmed 
147bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
14803fbed92SAli Ahmed 
149bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
150bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15103fbed92SAli Ahmed 
152bc1d29deSKrzysztof Grobelny     if (!success)
15303fbed92SAli Ahmed     {
15403fbed92SAli Ahmed         messages::internalError(aResp->res);
15503fbed92SAli Ahmed         return;
15603fbed92SAli Ahmed     }
15703fbed92SAli Ahmed 
158bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
15903fbed92SAli Ahmed     {
160bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
161bc1d29deSKrzysztof Grobelny             aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
162bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
163bc1d29deSKrzysztof Grobelny 
164bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
165bc1d29deSKrzysztof Grobelny         {
166bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
16703fbed92SAli Ahmed         }
16803fbed92SAli Ahmed         else
16903fbed92SAli Ahmed         {
170bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17103fbed92SAli Ahmed         }
17203fbed92SAli Ahmed     }
17303fbed92SAli Ahmed }
17403fbed92SAli Ahmed 
17503fbed92SAli Ahmed /*
17603fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
17703fbed92SAli Ahmed  *
17803fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
17903fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18003fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18103fbed92SAli Ahmed  *
18203fbed92SAli Ahmed  * @return None.
18303fbed92SAli Ahmed  */
18403fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18503fbed92SAli Ahmed                                 const std::string& service,
18603fbed92SAli Ahmed                                 const std::string& path)
18703fbed92SAli Ahmed {
18803fbed92SAli Ahmed 
1895e7e2dc5SEd Tanous     auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3,
190382d6475SAli Ahmed                                        const bool cpuPresenceCheck) {
191382d6475SAli Ahmed         if (ec3)
192382d6475SAli Ahmed         {
193382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
194382d6475SAli Ahmed             return;
195382d6475SAli Ahmed         }
196382d6475SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
197382d6475SAli Ahmed     };
198382d6475SAli Ahmed 
1995e7e2dc5SEd Tanous     auto getCpuFunctionalState = [aResp](const boost::system::error_code& ec3,
200382d6475SAli Ahmed                                          const bool cpuFunctionalCheck) {
201382d6475SAli Ahmed         if (ec3)
202382d6475SAli Ahmed         {
203382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
204382d6475SAli Ahmed             return;
205382d6475SAli Ahmed         }
206382d6475SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
207382d6475SAli Ahmed     };
208382d6475SAli Ahmed 
209382d6475SAli Ahmed     // Get the Presence of CPU
210382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
211382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
212382d6475SAli Ahmed         "xyz.openbmc_project.Inventory.Item", "Present",
213382d6475SAli Ahmed         std::move(getCpuPresenceState));
214382d6475SAli Ahmed 
215382d6475SAli Ahmed     // Get the Functional State
216382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
217382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
218382d6475SAli Ahmed         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
219382d6475SAli Ahmed         std::move(getCpuFunctionalState));
220382d6475SAli Ahmed 
221bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
222bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
223bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
22403fbed92SAli Ahmed         [aResp, service,
2255e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
226b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
22703fbed92SAli Ahmed         if (ec2)
22803fbed92SAli Ahmed         {
22903fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
23003fbed92SAli Ahmed             messages::internalError(aResp->res);
23103fbed92SAli Ahmed             return;
23203fbed92SAli Ahmed         }
233382d6475SAli Ahmed         getProcessorProperties(aResp, properties);
234bc1d29deSKrzysztof Grobelny         });
23503fbed92SAli Ahmed }
23603fbed92SAli Ahmed 
23757e8c9beSAlpana Kumari /*
238c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
239c5b2abe0SLewanczyk, Dawid  *
240c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2418f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
242c5b2abe0SLewanczyk, Dawid  *
243c5b2abe0SLewanczyk, Dawid  * @return None.
244c5b2abe0SLewanczyk, Dawid  */
245b5a76932SEd Tanous inline void
2468d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
247b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2481abe55efSEd Tanous {
24955c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
250e99073f5SGeorge Liu     constexpr std::array<std::string_view, 5> interfaces = {
251e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Decorator.Asset",
252e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Cpu",
253e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
254e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System",
255e99073f5SGeorge Liu         "xyz.openbmc_project.Common.UUID",
256e99073f5SGeorge Liu     };
257e99073f5SGeorge Liu     dbus::utility::getSubTree(
258e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
259b9d36b47SEd Tanous         [aResp,
260e99073f5SGeorge Liu          systemHealth](const boost::system::error_code& ec,
261b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
2621abe55efSEd Tanous         if (ec)
2631abe55efSEd Tanous         {
26455c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
265f12894f8SJason M. Bills             messages::internalError(aResp->res);
266c5b2abe0SLewanczyk, Dawid             return;
267c5b2abe0SLewanczyk, Dawid         }
268c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
269002d39b4SEd Tanous         for (const std::pair<
270002d39b4SEd Tanous                  std::string,
271002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
2721214b7e7SGunnar Mills                  object : subtree)
2731abe55efSEd Tanous         {
274c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
27555c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
276002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
2771214b7e7SGunnar Mills                 connectionNames = object.second;
27826f6976fSEd Tanous             if (connectionNames.empty())
2791abe55efSEd Tanous             {
280c5b2abe0SLewanczyk, Dawid                 continue;
281c5b2abe0SLewanczyk, Dawid             }
282029573d4SEd Tanous 
2835bc2dc8eSJames Feist             auto memoryHealth = std::make_shared<HealthPopulate>(
284dfababfcSNan Zhou                 aResp, "/MemorySummary/Status"_json_pointer);
2855bc2dc8eSJames Feist 
2865bc2dc8eSJames Feist             auto cpuHealth = std::make_shared<HealthPopulate>(
287dfababfcSNan Zhou                 aResp, "/ProcessorSummary/Status"_json_pointer);
2885bc2dc8eSJames Feist 
2895bc2dc8eSJames Feist             systemHealth->children.emplace_back(memoryHealth);
2905bc2dc8eSJames Feist             systemHealth->children.emplace_back(cpuHealth);
2915bc2dc8eSJames Feist 
2926c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
2936c34de48SEd Tanous             // BiosVer
29404a258f4SEd Tanous             for (const auto& connection : connectionNames)
2951abe55efSEd Tanous             {
29604a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
2971abe55efSEd Tanous                 {
29804a258f4SEd Tanous                     if (interfaceName ==
29904a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
3001abe55efSEd Tanous                     {
3011abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
30204a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
3039d3ae10eSAlpana Kumari 
304bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
305bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
306bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Inventory.Item.Dimm",
3079d3ae10eSAlpana Kumari                             [aResp, service{connection.first},
3085e7e2dc5SEd Tanous                              path](const boost::system::error_code& ec2,
309b9d36b47SEd Tanous                                    const dbus::utility::DBusPropertiesMap&
3101214b7e7SGunnar Mills                                        properties) {
311cb13a392SEd Tanous                             if (ec2)
3121abe55efSEd Tanous                             {
313002d39b4SEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error "
314002d39b4SEd Tanous                                                  << ec2;
315f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
316c5b2abe0SLewanczyk, Dawid                                 return;
317c5b2abe0SLewanczyk, Dawid                             }
318002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
319c5b2abe0SLewanczyk, Dawid                                              << " Dimm properties.";
3209d3ae10eSAlpana Kumari 
321bc1d29deSKrzysztof Grobelny                             if (properties.empty())
3229d3ae10eSAlpana Kumari                             {
3231e1e598dSJonathan Doman                                 sdbusplus::asio::getProperty<bool>(
324002d39b4SEd Tanous                                     *crow::connections::systemBus, service,
325002d39b4SEd Tanous                                     path,
3261e1e598dSJonathan Doman                                     "xyz.openbmc_project.State."
3271e1e598dSJonathan Doman                                     "Decorator.OperationalStatus",
3281e1e598dSJonathan Doman                                     "Functional",
3295e7e2dc5SEd Tanous                                     [aResp](
3305e7e2dc5SEd Tanous                                         const boost::system::error_code& ec3,
3311e1e598dSJonathan Doman                                         bool dimmState) {
332cb13a392SEd Tanous                                     if (ec3)
3339d3ae10eSAlpana Kumari                                     {
3349d3ae10eSAlpana Kumari                                         BMCWEB_LOG_ERROR
335002d39b4SEd Tanous                                             << "DBUS response error " << ec3;
3369d3ae10eSAlpana Kumari                                         return;
3379d3ae10eSAlpana Kumari                                     }
338002d39b4SEd Tanous                                     updateDimmProperties(aResp, dimmState);
3391e1e598dSJonathan Doman                                     });
340bc1d29deSKrzysztof Grobelny                                 return;
3419d3ae10eSAlpana Kumari                             }
342bc1d29deSKrzysztof Grobelny 
343bc1d29deSKrzysztof Grobelny                             const uint32_t* memorySizeInKB = nullptr;
344bc1d29deSKrzysztof Grobelny 
345bc1d29deSKrzysztof Grobelny                             const bool success =
346bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
347bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
348bc1d29deSKrzysztof Grobelny                                     properties, "MemorySizeInKB",
349bc1d29deSKrzysztof Grobelny                                     memorySizeInKB);
350bc1d29deSKrzysztof Grobelny 
351bc1d29deSKrzysztof Grobelny                             if (!success)
352bc1d29deSKrzysztof Grobelny                             {
353bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
354bc1d29deSKrzysztof Grobelny                                 return;
355bc1d29deSKrzysztof Grobelny                             }
356bc1d29deSKrzysztof Grobelny 
357bc1d29deSKrzysztof Grobelny                             if (memorySizeInKB != nullptr)
358bc1d29deSKrzysztof Grobelny                             {
359bc1d29deSKrzysztof Grobelny                                 nlohmann::json& totalMemory =
360bc1d29deSKrzysztof Grobelny                                     aResp->res
361bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
362bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"];
363bc1d29deSKrzysztof Grobelny                                 const uint64_t* preValue =
364bc1d29deSKrzysztof Grobelny                                     totalMemory.get_ptr<const uint64_t*>();
365bc1d29deSKrzysztof Grobelny                                 if (preValue == nullptr)
366bc1d29deSKrzysztof Grobelny                                 {
367bc1d29deSKrzysztof Grobelny                                     aResp->res
368bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
369bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
370bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024);
371bc1d29deSKrzysztof Grobelny                                 }
372bc1d29deSKrzysztof Grobelny                                 else
373bc1d29deSKrzysztof Grobelny                                 {
374bc1d29deSKrzysztof Grobelny                                     aResp->res
375bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
376bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
377bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024) +
378bc1d29deSKrzysztof Grobelny                                         *preValue;
379bc1d29deSKrzysztof Grobelny                                 }
380bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["MemorySummary"]["Status"]
381bc1d29deSKrzysztof Grobelny                                                     ["State"] = "Enabled";
382bc1d29deSKrzysztof Grobelny                             }
383bc1d29deSKrzysztof Grobelny                             });
3845bc2dc8eSJames Feist 
3855bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
3861abe55efSEd Tanous                     }
38704a258f4SEd Tanous                     else if (interfaceName ==
38804a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
3891abe55efSEd Tanous                     {
3901abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
39104a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
39257e8c9beSAlpana Kumari 
39303fbed92SAli Ahmed                         getProcessorSummary(aResp, connection.first, path);
3945bc2dc8eSJames Feist 
3955bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
3961abe55efSEd Tanous                     }
397002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
3981abe55efSEd Tanous                     {
3991abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
40004a258f4SEd Tanous                             << "Found UUID, now get its properties.";
401bc1d29deSKrzysztof Grobelny 
402bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
403bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
404bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
4055e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec3,
406b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4071214b7e7SGunnar Mills                                         properties) {
408cb13a392SEd Tanous                             if (ec3)
4091abe55efSEd Tanous                             {
410002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
411002d39b4SEd Tanous                                                  << ec3;
412f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
413c5b2abe0SLewanczyk, Dawid                                 return;
414c5b2abe0SLewanczyk, Dawid                             }
415002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
416c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
41704a258f4SEd Tanous 
418bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
419bc1d29deSKrzysztof Grobelny 
420bc1d29deSKrzysztof Grobelny                             const bool success =
421bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
422bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
423bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
424bc1d29deSKrzysztof Grobelny 
425bc1d29deSKrzysztof Grobelny                             if (!success)
4261abe55efSEd Tanous                             {
427bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
428bc1d29deSKrzysztof Grobelny                                 return;
429bc1d29deSKrzysztof Grobelny                             }
430bc1d29deSKrzysztof Grobelny 
431bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
432bc1d29deSKrzysztof Grobelny                             {
433bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
43404a258f4SEd Tanous                                 if (valueStr.size() == 32)
4351abe55efSEd Tanous                                 {
436029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
437029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
438029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
439029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
44004a258f4SEd Tanous                                 }
441bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
442002d39b4SEd Tanous                                 aResp->res.jsonValue["UUID"] = valueStr;
443c5b2abe0SLewanczyk, Dawid                             }
444bc1d29deSKrzysztof Grobelny                             });
445c5b2abe0SLewanczyk, Dawid                     }
446029573d4SEd Tanous                     else if (interfaceName ==
447029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4481abe55efSEd Tanous                     {
449bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
450bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
451bc1d29deSKrzysztof Grobelny                             path,
452bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
4535e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
454b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4551214b7e7SGunnar Mills                                         propertiesList) {
456cb13a392SEd Tanous                             if (ec2)
457029573d4SEd Tanous                             {
458e4a4b9a9SJames Feist                                 // doesn't have to include this
459e4a4b9a9SJames Feist                                 // interface
460029573d4SEd Tanous                                 return;
461029573d4SEd Tanous                             }
462002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
463029573d4SEd Tanous                                              << " properties for system";
464bc1d29deSKrzysztof Grobelny 
465bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
466bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
467bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
468bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
469bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
470bc1d29deSKrzysztof Grobelny 
471bc1d29deSKrzysztof Grobelny                             const bool success =
472bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
473bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
474bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
475bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
476bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
477bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
478bc1d29deSKrzysztof Grobelny 
479bc1d29deSKrzysztof Grobelny                             if (!success)
480029573d4SEd Tanous                             {
481bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
482bc1d29deSKrzysztof Grobelny                                 return;
483029573d4SEd Tanous                             }
484bc1d29deSKrzysztof Grobelny 
485bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
486bc1d29deSKrzysztof Grobelny                             {
487bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["PartNumber"] =
488bc1d29deSKrzysztof Grobelny                                     *partNumber;
489029573d4SEd Tanous                             }
490bc1d29deSKrzysztof Grobelny 
491bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
492bc1d29deSKrzysztof Grobelny                             {
493bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SerialNumber"] =
494bc1d29deSKrzysztof Grobelny                                     *serialNumber;
495bc1d29deSKrzysztof Grobelny                             }
496bc1d29deSKrzysztof Grobelny 
497bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
498bc1d29deSKrzysztof Grobelny                             {
499bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Manufacturer"] =
500bc1d29deSKrzysztof Grobelny                                     *manufacturer;
501bc1d29deSKrzysztof Grobelny                             }
502bc1d29deSKrzysztof Grobelny 
503bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
504bc1d29deSKrzysztof Grobelny                             {
505bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Model"] = *model;
506bc1d29deSKrzysztof Grobelny                             }
507bc1d29deSKrzysztof Grobelny 
508bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
509bc1d29deSKrzysztof Grobelny                             {
510bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SubModel"] = *subModel;
511fc5afcf9Sbeccabroek                             }
512c1e236a6SGunnar Mills 
513cb7e1e7bSAndrew Geissler                             // Grab the bios version
514eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
515eee0013eSWilly Tu                                 aResp, sw_util::biosPurpose, "BiosVersion",
516002d39b4SEd Tanous                                 false);
517bc1d29deSKrzysztof Grobelny                             });
518e4a4b9a9SJames Feist 
5191e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5201e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5211e1e598dSJonathan Doman                             path,
5221e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5231e1e598dSJonathan Doman                             "AssetTag",
5241e1e598dSJonathan Doman                             "AssetTag",
5255e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
5261e1e598dSJonathan Doman                                     const std::string& value) {
527cb13a392SEd Tanous                             if (ec2)
528e4a4b9a9SJames Feist                             {
529e4a4b9a9SJames Feist                                 // doesn't have to include this
530e4a4b9a9SJames Feist                                 // interface
531e4a4b9a9SJames Feist                                 return;
532e4a4b9a9SJames Feist                             }
533e4a4b9a9SJames Feist 
5341e1e598dSJonathan Doman                             aResp->res.jsonValue["AssetTag"] = value;
5351e1e598dSJonathan Doman                             });
536029573d4SEd Tanous                     }
537029573d4SEd Tanous                 }
538bc1d29deSKrzysztof Grobelny                 break;
539029573d4SEd Tanous             }
540c5b2abe0SLewanczyk, Dawid         }
5416617338dSEd Tanous         });
542c5b2abe0SLewanczyk, Dawid }
543c5b2abe0SLewanczyk, Dawid 
544c5b2abe0SLewanczyk, Dawid /**
545c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
546c5b2abe0SLewanczyk, Dawid  *
547c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
548c5b2abe0SLewanczyk, Dawid  *
549c5b2abe0SLewanczyk, Dawid  * @return None.
550c5b2abe0SLewanczyk, Dawid  */
5518d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5521abe55efSEd Tanous {
55355c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5541e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5551e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5561e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5571e1e598dSJonathan Doman         "CurrentHostState",
5585e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
5591e1e598dSJonathan Doman                 const std::string& hostState) {
5601abe55efSEd Tanous         if (ec)
5611abe55efSEd Tanous         {
56222228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
56322228c28SAndrew Geissler             {
56422228c28SAndrew Geissler                 // Service not available, no error, just don't return
56522228c28SAndrew Geissler                 // host state info
56622228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
56722228c28SAndrew Geissler                 return;
56822228c28SAndrew Geissler             }
56922228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
570f12894f8SJason M. Bills             messages::internalError(aResp->res);
571c5b2abe0SLewanczyk, Dawid             return;
572c5b2abe0SLewanczyk, Dawid         }
5736617338dSEd Tanous 
5741e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
575c5b2abe0SLewanczyk, Dawid         // Verify Host State
5761e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5771abe55efSEd Tanous         {
57855c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "On";
5796617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Enabled";
5801abe55efSEd Tanous         }
5811e1e598dSJonathan Doman         else if (hostState ==
5820fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
5838c888608SGunnar Mills         {
5848c888608SGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
5858c888608SGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Quiesced";
5868c888608SGunnar Mills         }
5871e1e598dSJonathan Doman         else if (hostState ==
5880fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
58983935af9SAndrew Geissler         {
59083935af9SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "On";
59183935af9SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "InTest";
59283935af9SAndrew Geissler         }
5930fda0f12SGeorge Liu         else if (
5941e1e598dSJonathan Doman             hostState ==
5950fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5961a2a1437SAndrew Geissler         {
5971a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOn";
59815c27bf8SNoah Brewer             aResp->res.jsonValue["Status"]["State"] = "Starting";
5991a2a1437SAndrew Geissler         }
600002d39b4SEd Tanous         else if (hostState ==
6010fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6021a2a1437SAndrew Geissler         {
6031a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOff";
6041a2a1437SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "Disabled";
6051a2a1437SAndrew Geissler         }
6061abe55efSEd Tanous         else
6071abe55efSEd Tanous         {
60855c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "Off";
6096617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Disabled";
610c5b2abe0SLewanczyk, Dawid         }
6111e1e598dSJonathan Doman         });
612c5b2abe0SLewanczyk, Dawid }
613c5b2abe0SLewanczyk, Dawid 
614c5b2abe0SLewanczyk, Dawid /**
615786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
616491d8ee7SSantosh Puranik  *
617491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
618491d8ee7SSantosh Puranik  *
619491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
620491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
621491d8ee7SSantosh Puranik  */
62223a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
623491d8ee7SSantosh Puranik {
624491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
625491d8ee7SSantosh Puranik     {
626491d8ee7SSantosh Puranik         return "None";
627491d8ee7SSantosh Puranik     }
6283174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
629491d8ee7SSantosh Puranik     {
630491d8ee7SSantosh Puranik         return "Hdd";
631491d8ee7SSantosh Puranik     }
6323174e4dfSEd Tanous     if (dbusSource ==
633a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
634491d8ee7SSantosh Puranik     {
635491d8ee7SSantosh Puranik         return "Cd";
636491d8ee7SSantosh Puranik     }
6373174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
638491d8ee7SSantosh Puranik     {
639491d8ee7SSantosh Puranik         return "Pxe";
640491d8ee7SSantosh Puranik     }
6413174e4dfSEd Tanous     if (dbusSource ==
642944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6439f16b2c1SJennifer Lee     {
6449f16b2c1SJennifer Lee         return "Usb";
6459f16b2c1SJennifer Lee     }
646491d8ee7SSantosh Puranik     return "";
647491d8ee7SSantosh Puranik }
648491d8ee7SSantosh Puranik 
649491d8ee7SSantosh Puranik /**
650cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
651cd9a4666SKonstantin Aladyshev  *
652cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
653cd9a4666SKonstantin Aladyshev  *
654cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
655cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
656cd9a4666SKonstantin Aladyshev  */
657cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
658cd9a4666SKonstantin Aladyshev {
659cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
660cd9a4666SKonstantin Aladyshev     {
661cd9a4666SKonstantin Aladyshev         return "Legacy";
662cd9a4666SKonstantin Aladyshev     }
663cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
664cd9a4666SKonstantin Aladyshev     {
665cd9a4666SKonstantin Aladyshev         return "UEFI";
666cd9a4666SKonstantin Aladyshev     }
667cd9a4666SKonstantin Aladyshev     return "";
668cd9a4666SKonstantin Aladyshev }
669cd9a4666SKonstantin Aladyshev 
670cd9a4666SKonstantin Aladyshev /**
671786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
672491d8ee7SSantosh Puranik  *
673491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
674491d8ee7SSantosh Puranik  *
675491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
676491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
677491d8ee7SSantosh Puranik  */
67823a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
679491d8ee7SSantosh Puranik {
680491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
681491d8ee7SSantosh Puranik     {
682491d8ee7SSantosh Puranik         return "None";
683491d8ee7SSantosh Puranik     }
6843174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
685491d8ee7SSantosh Puranik     {
686491d8ee7SSantosh Puranik         return "Diags";
687491d8ee7SSantosh Puranik     }
6883174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
689491d8ee7SSantosh Puranik     {
690491d8ee7SSantosh Puranik         return "BiosSetup";
691491d8ee7SSantosh Puranik     }
692491d8ee7SSantosh Puranik     return "";
693491d8ee7SSantosh Puranik }
694491d8ee7SSantosh Puranik 
695491d8ee7SSantosh Puranik /**
696e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
697e43914b3SAndrew Geissler  *
698e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
699e43914b3SAndrew Geissler  *
700e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
701e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
702e43914b3SAndrew Geissler  */
703e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
704e43914b3SAndrew Geissler {
705e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
706e43914b3SAndrew Geissler     // enum
707e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
708e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
709e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
710e43914b3SAndrew Geissler     {
711e43914b3SAndrew Geissler         rfBpLastState = "None";
712e43914b3SAndrew Geissler     }
713e43914b3SAndrew Geissler     else if (dbusBootProgress ==
714e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
715e43914b3SAndrew Geissler              "PrimaryProcInit")
716e43914b3SAndrew Geissler     {
717e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
718e43914b3SAndrew Geissler     }
719e43914b3SAndrew Geissler     else if (dbusBootProgress ==
720e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
721e43914b3SAndrew Geissler              "BusInit")
722e43914b3SAndrew Geissler     {
723e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
724e43914b3SAndrew Geissler     }
725e43914b3SAndrew Geissler     else if (dbusBootProgress ==
726e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
727e43914b3SAndrew Geissler              "MemoryInit")
728e43914b3SAndrew Geissler     {
729e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
730e43914b3SAndrew Geissler     }
731e43914b3SAndrew Geissler     else if (dbusBootProgress ==
732e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
733e43914b3SAndrew Geissler              "SecondaryProcInit")
734e43914b3SAndrew Geissler     {
735e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
736e43914b3SAndrew Geissler     }
737e43914b3SAndrew Geissler     else if (dbusBootProgress ==
738e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
739e43914b3SAndrew Geissler              "PCIInit")
740e43914b3SAndrew Geissler     {
741e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
742e43914b3SAndrew Geissler     }
743e43914b3SAndrew Geissler     else if (dbusBootProgress ==
744e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
745e43914b3SAndrew Geissler              "SystemSetup")
746e43914b3SAndrew Geissler     {
747e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
748e43914b3SAndrew Geissler     }
749e43914b3SAndrew Geissler     else if (dbusBootProgress ==
750e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
751e43914b3SAndrew Geissler              "SystemInitComplete")
752e43914b3SAndrew Geissler     {
753e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
754e43914b3SAndrew Geissler     }
755e43914b3SAndrew Geissler     else if (dbusBootProgress ==
756e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
757e43914b3SAndrew Geissler              "OSStart")
758e43914b3SAndrew Geissler     {
759e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
760e43914b3SAndrew Geissler     }
761e43914b3SAndrew Geissler     else if (dbusBootProgress ==
762e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
763e43914b3SAndrew Geissler              "OSRunning")
764e43914b3SAndrew Geissler     {
765e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
766e43914b3SAndrew Geissler     }
767e43914b3SAndrew Geissler     else
768e43914b3SAndrew Geissler     {
769e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
770e43914b3SAndrew Geissler                          << dbusBootProgress;
771e43914b3SAndrew Geissler         // Just return the default
772e43914b3SAndrew Geissler     }
773e43914b3SAndrew Geissler     return rfBpLastState;
774e43914b3SAndrew Geissler }
775e43914b3SAndrew Geissler 
776e43914b3SAndrew Geissler /**
777786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
778491d8ee7SSantosh Puranik  *
779491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
780944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
781944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
782491d8ee7SSantosh Puranik  *
783944ffaf9SJohnathan Mantey  * @return Integer error code.
784491d8ee7SSantosh Puranik  */
7858d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
786944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
787944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
788491d8ee7SSantosh Puranik {
789c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
790c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
791944ffaf9SJohnathan Mantey 
792491d8ee7SSantosh Puranik     if (rfSource == "None")
793491d8ee7SSantosh Puranik     {
794944ffaf9SJohnathan Mantey         return 0;
795491d8ee7SSantosh Puranik     }
7963174e4dfSEd Tanous     if (rfSource == "Pxe")
797491d8ee7SSantosh Puranik     {
798944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
799944ffaf9SJohnathan Mantey     }
800944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
801944ffaf9SJohnathan Mantey     {
802944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
803944ffaf9SJohnathan Mantey     }
804944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
805944ffaf9SJohnathan Mantey     {
806944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
807944ffaf9SJohnathan Mantey     }
808944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
809944ffaf9SJohnathan Mantey     {
810944ffaf9SJohnathan Mantey         bootSource =
811944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
812944ffaf9SJohnathan Mantey     }
813944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
814944ffaf9SJohnathan Mantey     {
815944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
816491d8ee7SSantosh Puranik     }
8179f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8189f16b2c1SJennifer Lee     {
819944ffaf9SJohnathan Mantey         bootSource =
820944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8219f16b2c1SJennifer Lee     }
822491d8ee7SSantosh Puranik     else
823491d8ee7SSantosh Puranik     {
8240fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8250fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
826944ffaf9SJohnathan Mantey             << bootSource;
827944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
828944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
829944ffaf9SJohnathan Mantey         return -1;
830491d8ee7SSantosh Puranik     }
831944ffaf9SJohnathan Mantey     return 0;
832491d8ee7SSantosh Puranik }
8331981771bSAli Ahmed 
834978b8803SAndrew Geissler /**
835978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
836978b8803SAndrew Geissler  *
837978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
838978b8803SAndrew Geissler  *
839978b8803SAndrew Geissler  * @return None.
840978b8803SAndrew Geissler  */
8418d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
842978b8803SAndrew Geissler {
8431e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8441e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8451e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8461e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
8475e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
8481e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
849978b8803SAndrew Geissler         if (ec)
850978b8803SAndrew Geissler         {
851978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
852978b8803SAndrew Geissler             // not found
853978b8803SAndrew Geissler             return;
854978b8803SAndrew Geissler         }
855978b8803SAndrew Geissler 
8561e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
857978b8803SAndrew Geissler 
858e43914b3SAndrew Geissler         aResp->res.jsonValue["BootProgress"]["LastState"] =
859e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8601e1e598dSJonathan Doman         });
861978b8803SAndrew Geissler }
862491d8ee7SSantosh Puranik 
863491d8ee7SSantosh Puranik /**
864b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
865b6d5d45cSHieu Huynh  *
866b6d5d45cSHieu Huynh  * @param[in] aResp  Shared pointer for generating response message.
867b6d5d45cSHieu Huynh  *
868b6d5d45cSHieu Huynh  * @return None.
869b6d5d45cSHieu Huynh  */
870b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
871b6d5d45cSHieu Huynh     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
872b6d5d45cSHieu Huynh {
873b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
874b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
875b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
876b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
8775e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
878b6d5d45cSHieu Huynh                 const uint64_t lastStateTime) {
879b6d5d45cSHieu Huynh         if (ec)
880b6d5d45cSHieu Huynh         {
881b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
882b6d5d45cSHieu Huynh             return;
883b6d5d45cSHieu Huynh         }
884b6d5d45cSHieu Huynh 
885b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
886b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
887b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
888b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
889b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
890b6d5d45cSHieu Huynh 
891b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
892b6d5d45cSHieu Huynh         aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
893b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
894b6d5d45cSHieu Huynh         });
895b6d5d45cSHieu Huynh }
896b6d5d45cSHieu Huynh 
897b6d5d45cSHieu Huynh /**
898c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
899cd9a4666SKonstantin Aladyshev  *
900cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
901cd9a4666SKonstantin Aladyshev  *
902cd9a4666SKonstantin Aladyshev  * @return None.
903cd9a4666SKonstantin Aladyshev  */
904cd9a4666SKonstantin Aladyshev 
905c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
906cd9a4666SKonstantin Aladyshev {
9071e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9081e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9091e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9101e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
9115e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9121e1e598dSJonathan Doman                 const std::string& bootType) {
913cd9a4666SKonstantin Aladyshev         if (ec)
914cd9a4666SKonstantin Aladyshev         {
915cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
916cd9a4666SKonstantin Aladyshev             return;
917cd9a4666SKonstantin Aladyshev         }
918cd9a4666SKonstantin Aladyshev 
9191e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
920cd9a4666SKonstantin Aladyshev 
921002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
922002d39b4SEd Tanous                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
923613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
924cd9a4666SKonstantin Aladyshev 
9251e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
926cd9a4666SKonstantin Aladyshev         if (rfType.empty())
927cd9a4666SKonstantin Aladyshev         {
928cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
929cd9a4666SKonstantin Aladyshev             return;
930cd9a4666SKonstantin Aladyshev         }
931cd9a4666SKonstantin Aladyshev 
932cd9a4666SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9331e1e598dSJonathan Doman         });
934cd9a4666SKonstantin Aladyshev }
935cd9a4666SKonstantin Aladyshev 
936cd9a4666SKonstantin Aladyshev /**
937c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
938491d8ee7SSantosh Puranik  *
939491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
940491d8ee7SSantosh Puranik  *
941491d8ee7SSantosh Puranik  * @return None.
942491d8ee7SSantosh Puranik  */
943c21865c4SKonstantin Aladyshev 
944c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
945491d8ee7SSantosh Puranik {
9461e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9471e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9481e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9491e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
9505e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9511e1e598dSJonathan Doman                 const std::string& bootModeStr) {
952491d8ee7SSantosh Puranik         if (ec)
953491d8ee7SSantosh Puranik         {
954491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
955491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
956491d8ee7SSantosh Puranik             return;
957491d8ee7SSantosh Puranik         }
958491d8ee7SSantosh Puranik 
9591e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
960491d8ee7SSantosh Puranik 
9610fda0f12SGeorge Liu         aResp->res
9620fda0f12SGeorge Liu             .jsonValue["Boot"]
963002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
964002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
965491d8ee7SSantosh Puranik 
9661e1e598dSJonathan Doman         if (bootModeStr !=
967491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
968491d8ee7SSantosh Puranik         {
9691e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
970491d8ee7SSantosh Puranik             if (!rfMode.empty())
971491d8ee7SSantosh Puranik             {
972491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
973491d8ee7SSantosh Puranik                     rfMode;
974491d8ee7SSantosh Puranik             }
975491d8ee7SSantosh Puranik         }
9761e1e598dSJonathan Doman         });
977491d8ee7SSantosh Puranik }
978491d8ee7SSantosh Puranik 
979491d8ee7SSantosh Puranik /**
980c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
981491d8ee7SSantosh Puranik  *
982491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
983491d8ee7SSantosh Puranik  *
984491d8ee7SSantosh Puranik  * @return None.
985491d8ee7SSantosh Puranik  */
986c21865c4SKonstantin Aladyshev 
987c21865c4SKonstantin Aladyshev inline void
988c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
989491d8ee7SSantosh Puranik {
9901e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9911e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9921e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9931e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
9945e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9951e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
996491d8ee7SSantosh Puranik         if (ec)
997491d8ee7SSantosh Puranik         {
998491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
9995ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10005ef735c8SNan Zhou             {
10015ef735c8SNan Zhou                 return;
10025ef735c8SNan Zhou             }
1003491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1004491d8ee7SSantosh Puranik             return;
1005491d8ee7SSantosh Puranik         }
1006491d8ee7SSantosh Puranik 
10071e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1008491d8ee7SSantosh Puranik 
10091e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1010491d8ee7SSantosh Puranik         if (!rfSource.empty())
1011491d8ee7SSantosh Puranik         {
1012002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1013491d8ee7SSantosh Puranik         }
1014cd9a4666SKonstantin Aladyshev 
1015cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1016cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1017c21865c4SKonstantin Aladyshev         getBootOverrideMode(aResp);
10181e1e598dSJonathan Doman         });
1019491d8ee7SSantosh Puranik }
1020491d8ee7SSantosh Puranik 
1021491d8ee7SSantosh Puranik /**
1022c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1023c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1024c21865c4SKonstantin Aladyshev  * state
1025491d8ee7SSantosh Puranik  *
1026491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1027491d8ee7SSantosh Puranik  *
1028491d8ee7SSantosh Puranik  * @return None.
1029491d8ee7SSantosh Puranik  */
1030491d8ee7SSantosh Puranik 
1031c21865c4SKonstantin Aladyshev inline void
1032c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1033c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1034c21865c4SKonstantin Aladyshev {
1035c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1036c21865c4SKonstantin Aladyshev     {
1037c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1038c21865c4SKonstantin Aladyshev         return;
1039c21865c4SKonstantin Aladyshev     }
1040c21865c4SKonstantin Aladyshev 
1041c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1042c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10431e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10441e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10451e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10461e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10475e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1048491d8ee7SSantosh Puranik         if (ec)
1049491d8ee7SSantosh Puranik         {
1050491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1051c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1052491d8ee7SSantosh Puranik             return;
1053491d8ee7SSantosh Puranik         }
1054491d8ee7SSantosh Puranik 
1055c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1056c21865c4SKonstantin Aladyshev         {
1057002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1058c21865c4SKonstantin Aladyshev         }
1059c21865c4SKonstantin Aladyshev         else
1060c21865c4SKonstantin Aladyshev         {
1061c21865c4SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1062c21865c4SKonstantin Aladyshev                 "Continuous";
1063c21865c4SKonstantin Aladyshev         }
10641e1e598dSJonathan Doman         });
1065491d8ee7SSantosh Puranik }
1066491d8ee7SSantosh Puranik 
1067491d8ee7SSantosh Puranik /**
1068c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1069c21865c4SKonstantin Aladyshev  *
1070c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1071c21865c4SKonstantin Aladyshev  *
1072c21865c4SKonstantin Aladyshev  * @return None.
1073c21865c4SKonstantin Aladyshev  */
1074c21865c4SKonstantin Aladyshev 
1075c21865c4SKonstantin Aladyshev inline void
1076c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1077c21865c4SKonstantin Aladyshev {
10781e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10791e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10801e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10811e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10825e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
10831e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1084c21865c4SKonstantin Aladyshev         if (ec)
1085c21865c4SKonstantin Aladyshev         {
1086c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10875ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10885ef735c8SNan Zhou             {
10895ef735c8SNan Zhou                 return;
10905ef735c8SNan Zhou             }
1091c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1092c21865c4SKonstantin Aladyshev             return;
1093c21865c4SKonstantin Aladyshev         }
1094c21865c4SKonstantin Aladyshev 
10951e1e598dSJonathan Doman         processBootOverrideEnable(aResp, bootOverrideEnable);
10961e1e598dSJonathan Doman         });
1097c21865c4SKonstantin Aladyshev }
1098c21865c4SKonstantin Aladyshev 
1099c21865c4SKonstantin Aladyshev /**
1100c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1101c21865c4SKonstantin Aladyshev  *
1102c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1103c21865c4SKonstantin Aladyshev  *
1104c21865c4SKonstantin Aladyshev  * @return None.
1105c21865c4SKonstantin Aladyshev  */
1106c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1107c21865c4SKonstantin Aladyshev {
1108c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1109c21865c4SKonstantin Aladyshev 
1110c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1111c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1112c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1113c21865c4SKonstantin Aladyshev }
1114c21865c4SKonstantin Aladyshev 
1115c21865c4SKonstantin Aladyshev /**
1116c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1117c0557e1aSGunnar Mills  *
1118c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1119c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1120c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1121c0557e1aSGunnar Mills  * last power operation time.
1122c0557e1aSGunnar Mills  *
1123c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1124c0557e1aSGunnar Mills  *
1125c0557e1aSGunnar Mills  * @return None.
1126c0557e1aSGunnar Mills  */
11278d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1128c0557e1aSGunnar Mills {
1129c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1130c0557e1aSGunnar Mills 
11311e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11321e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11331e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11341e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
11355e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) {
1136c0557e1aSGunnar Mills         if (ec)
1137c0557e1aSGunnar Mills         {
1138c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1139c0557e1aSGunnar Mills             return;
1140c0557e1aSGunnar Mills         }
1141c0557e1aSGunnar Mills 
1142c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1143c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11441e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1145c0557e1aSGunnar Mills 
1146c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1147c0557e1aSGunnar Mills         aResp->res.jsonValue["LastResetTime"] =
11482b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11491e1e598dSJonathan Doman         });
1150c0557e1aSGunnar Mills }
1151c0557e1aSGunnar Mills 
1152c0557e1aSGunnar Mills /**
11536bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11546bd5a8d2SGunnar Mills  *
11556bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11566bd5a8d2SGunnar Mills  *
11576bd5a8d2SGunnar Mills  * @return None.
11586bd5a8d2SGunnar Mills  */
11598d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11606bd5a8d2SGunnar Mills {
11616bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
11626bd5a8d2SGunnar Mills 
11631e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11641e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11651e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
11661e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
11675e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) {
11686bd5a8d2SGunnar Mills         if (ec)
11696bd5a8d2SGunnar Mills         {
11706bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
11716bd5a8d2SGunnar Mills             return;
11726bd5a8d2SGunnar Mills         }
11736bd5a8d2SGunnar Mills 
11741e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1175e05aec50SEd Tanous         if (autoRebootEnabled)
11766bd5a8d2SGunnar Mills         {
11776bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11786bd5a8d2SGunnar Mills                 "RetryAttempts";
11796bd5a8d2SGunnar Mills             // If AutomaticRetry (AutoReboot) is enabled see how many
11806bd5a8d2SGunnar Mills             // attempts are left
11811e1e598dSJonathan Doman             sdbusplus::asio::getProperty<uint32_t>(
1182002d39b4SEd Tanous                 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
11831e1e598dSJonathan Doman                 "/xyz/openbmc_project/state/host0",
11841e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.Boot.RebootAttempts",
11851e1e598dSJonathan Doman                 "AttemptsLeft",
11865e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2,
1187914e2d5dSEd Tanous                         const uint32_t autoRebootAttemptsLeft) {
1188cb13a392SEd Tanous                 if (ec2)
11896bd5a8d2SGunnar Mills                 {
1190cb13a392SEd Tanous                     BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
11916bd5a8d2SGunnar Mills                     return;
11926bd5a8d2SGunnar Mills                 }
11936bd5a8d2SGunnar Mills 
11946bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
11951e1e598dSJonathan Doman                                  << autoRebootAttemptsLeft;
11966bd5a8d2SGunnar Mills 
11976bd5a8d2SGunnar Mills                 aResp->res
1198002d39b4SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
11991e1e598dSJonathan Doman                     autoRebootAttemptsLeft;
12001e1e598dSJonathan Doman                 });
12016bd5a8d2SGunnar Mills         }
12026bd5a8d2SGunnar Mills         else
12036bd5a8d2SGunnar Mills         {
1204002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
12056bd5a8d2SGunnar Mills         }
12066bd5a8d2SGunnar Mills 
12076bd5a8d2SGunnar Mills         // Not on D-Bus. Hardcoded here:
12086bd5a8d2SGunnar Mills         // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
12096bd5a8d2SGunnar Mills         aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
121069f35306SGunnar Mills 
121169f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
121269f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
121369f35306SGunnar Mills         // RetryAttempts.
1214002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
12150fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
12160fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
12171e1e598dSJonathan Doman         });
12186bd5a8d2SGunnar Mills }
12196bd5a8d2SGunnar Mills 
12206bd5a8d2SGunnar Mills /**
1221c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1222c6a620f2SGeorge Liu  *
1223c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1224c6a620f2SGeorge Liu  *
1225c6a620f2SGeorge Liu  * @return None.
1226c6a620f2SGeorge Liu  */
12278d1b46d7Szhanghch05 inline void
12288d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1229c6a620f2SGeorge Liu {
1230c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1231c6a620f2SGeorge Liu 
12321e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
12331e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12341e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
12351e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
12365e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
12375e7e2dc5SEd Tanous                 const std::string& policy) {
1238c6a620f2SGeorge Liu         if (ec)
1239c6a620f2SGeorge Liu         {
1240c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1241c6a620f2SGeorge Liu             return;
1242c6a620f2SGeorge Liu         }
1243c6a620f2SGeorge Liu 
12440fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
12450fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1246c6a620f2SGeorge Liu              "AlwaysOn"},
12470fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1248c6a620f2SGeorge Liu              "AlwaysOff"},
12490fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
12504ed47cb8SMatthew Barth              "LastState"},
12514ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
12524ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
12534ed47cb8SMatthew Barth              "AlwaysOff"}};
1254c6a620f2SGeorge Liu 
12551e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1256c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1257c6a620f2SGeorge Liu         {
1258c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1259c6a620f2SGeorge Liu             return;
1260c6a620f2SGeorge Liu         }
1261c6a620f2SGeorge Liu 
1262c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
12631e1e598dSJonathan Doman         });
1264c6a620f2SGeorge Liu }
1265c6a620f2SGeorge Liu 
1266c6a620f2SGeorge Liu /**
12671981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
12681981771bSAli Ahmed  * TPM is required for booting the host.
12691981771bSAli Ahmed  *
12701981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
12711981771bSAli Ahmed  *
12721981771bSAli Ahmed  * @return None.
12731981771bSAli Ahmed  */
12741981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
12751981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12761981771bSAli Ahmed {
12771981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1278e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1279e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1280e99073f5SGeorge Liu     dbus::utility::getSubTree(
1281e99073f5SGeorge Liu         "/", 0, interfaces,
1282e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1283b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
12841981771bSAli Ahmed         if (ec)
12851981771bSAli Ahmed         {
1286002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1287002d39b4SEd Tanous                              << ec;
12881981771bSAli Ahmed             // This is an optional D-Bus object so just return if
12891981771bSAli Ahmed             // error occurs
12901981771bSAli Ahmed             return;
12911981771bSAli Ahmed         }
129226f6976fSEd Tanous         if (subtree.empty())
12931981771bSAli Ahmed         {
12941981771bSAli Ahmed             // As noted above, this is an optional interface so just return
12951981771bSAli Ahmed             // if there is no instance found
12961981771bSAli Ahmed             return;
12971981771bSAli Ahmed         }
12981981771bSAli Ahmed 
12991981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
13001981771bSAli Ahmed         if (subtree.size() > 1)
13011981771bSAli Ahmed         {
13021981771bSAli Ahmed             BMCWEB_LOG_DEBUG
13031981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13041981771bSAli Ahmed                 << subtree.size();
13051981771bSAli Ahmed             // Throw an internal Error and return
13061981771bSAli Ahmed             messages::internalError(aResp->res);
13071981771bSAli Ahmed             return;
13081981771bSAli Ahmed         }
13091981771bSAli Ahmed 
13101981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13111981771bSAli Ahmed         // field
13121981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13131981771bSAli Ahmed         {
13141981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13151981771bSAli Ahmed             messages::internalError(aResp->res);
13161981771bSAli Ahmed             return;
13171981771bSAli Ahmed         }
13181981771bSAli Ahmed 
13191981771bSAli Ahmed         const std::string& path = subtree[0].first;
13201981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
13211981771bSAli Ahmed 
13221981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
13231e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
13241e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
13251e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
13265e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
13278a592810SEd Tanous             if (ec2)
13281981771bSAli Ahmed             {
1329002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
13308a592810SEd Tanous                                  << ec2;
13311981771bSAli Ahmed                 messages::internalError(aResp->res);
13321981771bSAli Ahmed                 return;
13331981771bSAli Ahmed             }
13341981771bSAli Ahmed 
13351e1e598dSJonathan Doman             if (tpmRequired)
13361981771bSAli Ahmed             {
1337002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
13381981771bSAli Ahmed                     "Required";
13391981771bSAli Ahmed             }
13401981771bSAli Ahmed             else
13411981771bSAli Ahmed             {
1342002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
13431981771bSAli Ahmed                     "Disabled";
13441981771bSAli Ahmed             }
13451e1e598dSJonathan Doman             });
1346e99073f5SGeorge Liu         });
13471981771bSAli Ahmed }
13481981771bSAli Ahmed 
13491981771bSAli Ahmed /**
13501c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
13511c05dae3SAli Ahmed  * TPM is required for booting the host.
13521c05dae3SAli Ahmed  *
13531c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
13541c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
13551c05dae3SAli Ahmed  *
13561c05dae3SAli Ahmed  * @return None.
13571c05dae3SAli Ahmed  */
13581c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
13591c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
13601c05dae3SAli Ahmed {
13611c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1362e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1363e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1364e99073f5SGeorge Liu     dbus::utility::getSubTree(
1365e99073f5SGeorge Liu         "/", 0, interfaces,
1366e99073f5SGeorge Liu         [aResp,
1367e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1368e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
13691c05dae3SAli Ahmed         if (ec)
13701c05dae3SAli Ahmed         {
1371002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1372002d39b4SEd Tanous                              << ec;
13731c05dae3SAli Ahmed             messages::internalError(aResp->res);
13741c05dae3SAli Ahmed             return;
13751c05dae3SAli Ahmed         }
137626f6976fSEd Tanous         if (subtree.empty())
13771c05dae3SAli Ahmed         {
13781c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
13791c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
13801c05dae3SAli Ahmed             return;
13811c05dae3SAli Ahmed         }
13821c05dae3SAli Ahmed 
13831c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
13841c05dae3SAli Ahmed         if (subtree.size() > 1)
13851c05dae3SAli Ahmed         {
13861c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
13871c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13881c05dae3SAli Ahmed                 << subtree.size();
13891c05dae3SAli Ahmed             // Throw an internal Error and return
13901c05dae3SAli Ahmed             messages::internalError(aResp->res);
13911c05dae3SAli Ahmed             return;
13921c05dae3SAli Ahmed         }
13931c05dae3SAli Ahmed 
13941c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13951c05dae3SAli Ahmed         // field
13961c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13971c05dae3SAli Ahmed         {
13981c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13991c05dae3SAli Ahmed             messages::internalError(aResp->res);
14001c05dae3SAli Ahmed             return;
14011c05dae3SAli Ahmed         }
14021c05dae3SAli Ahmed 
14031c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
14041c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14051c05dae3SAli Ahmed 
14061c05dae3SAli Ahmed         if (serv.empty())
14071c05dae3SAli Ahmed         {
14081c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
14091c05dae3SAli Ahmed             messages::internalError(aResp->res);
14101c05dae3SAli Ahmed             return;
14111c05dae3SAli Ahmed         }
14121c05dae3SAli Ahmed 
14131c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
14141c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
14155e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
14168a592810SEd Tanous             if (ec2)
14171c05dae3SAli Ahmed             {
14180fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
14190fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
14208a592810SEd Tanous                     << ec2;
14211c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14221c05dae3SAli Ahmed                 return;
14231c05dae3SAli Ahmed             }
14241c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
14251c05dae3SAli Ahmed             },
14261c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
14271c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1428168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
1429e99073f5SGeorge Liu         });
14301c05dae3SAli Ahmed }
14311c05dae3SAli Ahmed 
14321c05dae3SAli Ahmed /**
1433491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1434491d8ee7SSantosh Puranik  *
1435491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1436cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1437cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1438cd9a4666SKonstantin Aladyshev  */
1439cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1440cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1441cd9a4666SKonstantin Aladyshev {
1442c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1443cd9a4666SKonstantin Aladyshev 
1444c21865c4SKonstantin Aladyshev     if (!bootType)
1445cd9a4666SKonstantin Aladyshev     {
1446c21865c4SKonstantin Aladyshev         return;
1447c21865c4SKonstantin Aladyshev     }
1448c21865c4SKonstantin Aladyshev 
1449cd9a4666SKonstantin Aladyshev     // Source target specified
1450cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1451cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1452cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1453cd9a4666SKonstantin Aladyshev     {
1454cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1455cd9a4666SKonstantin Aladyshev     }
1456cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1457cd9a4666SKonstantin Aladyshev     {
1458cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1459cd9a4666SKonstantin Aladyshev     }
1460cd9a4666SKonstantin Aladyshev     else
1461cd9a4666SKonstantin Aladyshev     {
1462cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1463cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1464cd9a4666SKonstantin Aladyshev                          << *bootType;
1465cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1466cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1467cd9a4666SKonstantin Aladyshev         return;
1468cd9a4666SKonstantin Aladyshev     }
1469cd9a4666SKonstantin Aladyshev 
1470cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1471cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1472cd9a4666SKonstantin Aladyshev 
1473cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
14745e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1475cd9a4666SKonstantin Aladyshev         if (ec)
1476cd9a4666SKonstantin Aladyshev         {
1477cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1478cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1479cd9a4666SKonstantin Aladyshev             {
1480cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1481cd9a4666SKonstantin Aladyshev                 return;
1482cd9a4666SKonstantin Aladyshev             }
1483cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1484cd9a4666SKonstantin Aladyshev             return;
1485cd9a4666SKonstantin Aladyshev         }
1486cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1487cd9a4666SKonstantin Aladyshev         },
1488c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1489c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1490cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1491cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1492168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1493cd9a4666SKonstantin Aladyshev }
1494cd9a4666SKonstantin Aladyshev 
1495cd9a4666SKonstantin Aladyshev /**
1496cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1497cd9a4666SKonstantin Aladyshev  *
1498cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1499c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1500c21865c4SKonstantin Aladyshev  * @return Integer error code.
1501c21865c4SKonstantin Aladyshev  */
1502c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1503c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1504c21865c4SKonstantin Aladyshev {
1505c21865c4SKonstantin Aladyshev     if (!bootEnable)
1506c21865c4SKonstantin Aladyshev     {
1507c21865c4SKonstantin Aladyshev         return;
1508c21865c4SKonstantin Aladyshev     }
1509c21865c4SKonstantin Aladyshev     // Source target specified
1510c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1511c21865c4SKonstantin Aladyshev 
1512c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1513c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1514c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1515c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1516c21865c4SKonstantin Aladyshev     {
1517c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1518c21865c4SKonstantin Aladyshev     }
1519c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1520c21865c4SKonstantin Aladyshev     {
1521c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1522c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1523c21865c4SKonstantin Aladyshev     }
1524c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1525c21865c4SKonstantin Aladyshev     {
1526c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1527c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1528c21865c4SKonstantin Aladyshev     }
1529c21865c4SKonstantin Aladyshev     else
1530c21865c4SKonstantin Aladyshev     {
15310fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
15320fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1533c21865c4SKonstantin Aladyshev             << *bootEnable;
1534c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1535c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1536c21865c4SKonstantin Aladyshev         return;
1537c21865c4SKonstantin Aladyshev     }
1538c21865c4SKonstantin Aladyshev 
1539c21865c4SKonstantin Aladyshev     // Act on validated parameters
1540c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1541c21865c4SKonstantin Aladyshev 
1542c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
15435e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec2) {
15448a592810SEd Tanous         if (ec2)
1545c21865c4SKonstantin Aladyshev         {
15468a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1547c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1548c21865c4SKonstantin Aladyshev             return;
1549c21865c4SKonstantin Aladyshev         }
1550c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1551c21865c4SKonstantin Aladyshev         },
1552c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1553c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1554c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1555c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1556168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1557c21865c4SKonstantin Aladyshev 
1558c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1559c21865c4SKonstantin Aladyshev     {
1560c21865c4SKonstantin Aladyshev         return;
1561c21865c4SKonstantin Aladyshev     }
1562c21865c4SKonstantin Aladyshev 
1563c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1564c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1565c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1566c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1567c21865c4SKonstantin Aladyshev 
1568c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
15695e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1570c21865c4SKonstantin Aladyshev         if (ec)
1571c21865c4SKonstantin Aladyshev         {
1572c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1573c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1574c21865c4SKonstantin Aladyshev             return;
1575c21865c4SKonstantin Aladyshev         }
1576c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1577c21865c4SKonstantin Aladyshev         },
1578c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1579c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1580c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1581c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1582168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1583c21865c4SKonstantin Aladyshev }
1584c21865c4SKonstantin Aladyshev 
1585c21865c4SKonstantin Aladyshev /**
1586c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1587c21865c4SKonstantin Aladyshev  *
1588c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1589491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1590491d8ee7SSantosh Puranik  *
1591265c1602SJohnathan Mantey  * @return Integer error code.
1592491d8ee7SSantosh Puranik  */
1593cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1594cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1595491d8ee7SSantosh Puranik {
1596c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1597c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1598944ffaf9SJohnathan Mantey 
1599c21865c4SKonstantin Aladyshev     if (!bootSource)
1600491d8ee7SSantosh Puranik     {
1601c21865c4SKonstantin Aladyshev         return;
1602c21865c4SKonstantin Aladyshev     }
1603c21865c4SKonstantin Aladyshev 
1604491d8ee7SSantosh Puranik     // Source target specified
1605491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1606491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1607e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1608e662eae8SEd Tanous         0)
1609491d8ee7SSantosh Puranik     {
1610944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1611944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1612491d8ee7SSantosh Puranik             << *bootSource;
1613491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1614491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1615491d8ee7SSantosh Puranik         return;
1616491d8ee7SSantosh Puranik     }
1617491d8ee7SSantosh Puranik 
1618944ffaf9SJohnathan Mantey     // Act on validated parameters
1619944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1620944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1621944ffaf9SJohnathan Mantey 
1622491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
16235e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1624491d8ee7SSantosh Puranik         if (ec)
1625491d8ee7SSantosh Puranik         {
1626491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1627491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1628491d8ee7SSantosh Puranik             return;
1629491d8ee7SSantosh Puranik         }
1630491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1631491d8ee7SSantosh Puranik         },
1632c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1633c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1634491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1635491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1636168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1637944ffaf9SJohnathan Mantey 
1638491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
16395e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1640491d8ee7SSantosh Puranik         if (ec)
1641491d8ee7SSantosh Puranik         {
1642491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1643491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1644491d8ee7SSantosh Puranik             return;
1645491d8ee7SSantosh Puranik         }
1646491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1647491d8ee7SSantosh Puranik         },
1648c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1649c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1650491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1651491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1652168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1653cd9a4666SKonstantin Aladyshev }
1654944ffaf9SJohnathan Mantey 
1655cd9a4666SKonstantin Aladyshev /**
1656c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1657491d8ee7SSantosh Puranik  *
1658491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1659491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1660cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1661491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1662491d8ee7SSantosh Puranik  *
1663265c1602SJohnathan Mantey  * @return Integer error code.
1664491d8ee7SSantosh Puranik  */
1665c21865c4SKonstantin Aladyshev 
1666c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1667c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1668c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1669c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1670491d8ee7SSantosh Puranik {
1671491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1672491d8ee7SSantosh Puranik 
1673c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1674c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1675c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1676491d8ee7SSantosh Puranik }
1677491d8ee7SSantosh Puranik 
1678c6a620f2SGeorge Liu /**
167998e386ecSGunnar Mills  * @brief Sets AssetTag
168098e386ecSGunnar Mills  *
168198e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
168298e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
168398e386ecSGunnar Mills  *
168498e386ecSGunnar Mills  * @return None.
168598e386ecSGunnar Mills  */
16868d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
168798e386ecSGunnar Mills                         const std::string& assetTag)
168898e386ecSGunnar Mills {
1689e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1690e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1691e99073f5SGeorge Liu     dbus::utility::getSubTree(
1692e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1693b9d36b47SEd Tanous         [aResp,
1694e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1695b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
169698e386ecSGunnar Mills         if (ec)
169798e386ecSGunnar Mills         {
169898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
169998e386ecSGunnar Mills             messages::internalError(aResp->res);
170098e386ecSGunnar Mills             return;
170198e386ecSGunnar Mills         }
170226f6976fSEd Tanous         if (subtree.empty())
170398e386ecSGunnar Mills         {
170498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
170598e386ecSGunnar Mills             messages::internalError(aResp->res);
170698e386ecSGunnar Mills             return;
170798e386ecSGunnar Mills         }
170898e386ecSGunnar Mills         // Assume only 1 system D-Bus object
170998e386ecSGunnar Mills         // Throw an error if there is more than 1
171098e386ecSGunnar Mills         if (subtree.size() > 1)
171198e386ecSGunnar Mills         {
171298e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
171398e386ecSGunnar Mills             messages::internalError(aResp->res);
171498e386ecSGunnar Mills             return;
171598e386ecSGunnar Mills         }
171698e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
171798e386ecSGunnar Mills         {
171898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
171998e386ecSGunnar Mills             messages::internalError(aResp->res);
172098e386ecSGunnar Mills             return;
172198e386ecSGunnar Mills         }
172298e386ecSGunnar Mills 
172398e386ecSGunnar Mills         const std::string& path = subtree[0].first;
172498e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
172598e386ecSGunnar Mills 
172698e386ecSGunnar Mills         if (service.empty())
172798e386ecSGunnar Mills         {
172898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
172998e386ecSGunnar Mills             messages::internalError(aResp->res);
173098e386ecSGunnar Mills             return;
173198e386ecSGunnar Mills         }
173298e386ecSGunnar Mills 
173398e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
17345e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
173598e386ecSGunnar Mills             if (ec2)
173698e386ecSGunnar Mills             {
1737002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1738002d39b4SEd Tanous                                  << ec2;
173998e386ecSGunnar Mills                 messages::internalError(aResp->res);
174098e386ecSGunnar Mills                 return;
174198e386ecSGunnar Mills             }
174298e386ecSGunnar Mills             },
174398e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
174498e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1745168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
1746e99073f5SGeorge Liu         });
174798e386ecSGunnar Mills }
174898e386ecSGunnar Mills 
174998e386ecSGunnar Mills /**
175069f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
175169f35306SGunnar Mills  *
175269f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
175369f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
175469f35306SGunnar Mills  *
175569f35306SGunnar Mills  * @return None.
175669f35306SGunnar Mills  */
17578d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1758f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
175969f35306SGunnar Mills {
176069f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
176169f35306SGunnar Mills 
176269f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1763543f4400SEd Tanous     bool autoRebootEnabled = false;
176469f35306SGunnar Mills 
176569f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
176669f35306SGunnar Mills     {
176769f35306SGunnar Mills         autoRebootEnabled = false;
176869f35306SGunnar Mills     }
176969f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
177069f35306SGunnar Mills     {
177169f35306SGunnar Mills         autoRebootEnabled = true;
177269f35306SGunnar Mills     }
177369f35306SGunnar Mills     else
177469f35306SGunnar Mills     {
17750fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
177669f35306SGunnar Mills                          << automaticRetryConfig;
177769f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
177869f35306SGunnar Mills                                          "AutomaticRetryConfig");
177969f35306SGunnar Mills         return;
178069f35306SGunnar Mills     }
178169f35306SGunnar Mills 
178269f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
17835e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
178469f35306SGunnar Mills         if (ec)
178569f35306SGunnar Mills         {
178669f35306SGunnar Mills             messages::internalError(aResp->res);
178769f35306SGunnar Mills             return;
178869f35306SGunnar Mills         }
178969f35306SGunnar Mills         },
179069f35306SGunnar Mills         "xyz.openbmc_project.Settings",
179169f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
179269f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
179369f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1794168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
179569f35306SGunnar Mills }
179669f35306SGunnar Mills 
179769f35306SGunnar Mills /**
1798c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1799c6a620f2SGeorge Liu  *
1800c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1801c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1802c6a620f2SGeorge Liu  *
1803c6a620f2SGeorge Liu  * @return None.
1804c6a620f2SGeorge Liu  */
18058d1b46d7Szhanghch05 inline void
18068d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18074e69c904SGunnar Mills                           const std::string& policy)
1808c6a620f2SGeorge Liu {
1809c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1810c6a620f2SGeorge Liu 
1811c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
18120fda0f12SGeorge Liu         {"AlwaysOn",
18130fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
18140fda0f12SGeorge Liu         {"AlwaysOff",
18150fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
18160fda0f12SGeorge Liu         {"LastState",
18170fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1818c6a620f2SGeorge Liu 
1819c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1820c6a620f2SGeorge Liu 
18214e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1822c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1823c6a620f2SGeorge Liu     {
18244e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
18254e69c904SGunnar Mills                                          "PowerRestorePolicy");
1826c6a620f2SGeorge Liu         return;
1827c6a620f2SGeorge Liu     }
1828c6a620f2SGeorge Liu 
1829c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1830c6a620f2SGeorge Liu 
1831c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
18325e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1833c6a620f2SGeorge Liu         if (ec)
1834c6a620f2SGeorge Liu         {
1835c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1836c6a620f2SGeorge Liu             return;
1837c6a620f2SGeorge Liu         }
1838c6a620f2SGeorge Liu         },
1839c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1840c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1841c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1842c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1843168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1844c6a620f2SGeorge Liu }
1845c6a620f2SGeorge Liu 
1846a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1847a6349918SAppaRao Puli /**
1848a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1849a6349918SAppaRao Puli  *
1850a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1851a6349918SAppaRao Puli  *
1852a6349918SAppaRao Puli  * @return None.
1853a6349918SAppaRao Puli  */
18548d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1855a6349918SAppaRao Puli {
1856a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1857bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1858bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1859bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
18605e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
1861b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1862b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1863b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
186450626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
186550626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
186650626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
186750626f4fSJames Feist 
1868a6349918SAppaRao Puli         if (ec)
1869a6349918SAppaRao Puli         {
1870a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1871b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1872b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1873a6349918SAppaRao Puli             return;
1874a6349918SAppaRao Puli         }
1875a6349918SAppaRao Puli 
1876a6349918SAppaRao Puli         const bool* provState = nullptr;
1877a6349918SAppaRao Puli         const bool* lockState = nullptr;
1878bc1d29deSKrzysztof Grobelny 
1879bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
18800d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
18810d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1882bc1d29deSKrzysztof Grobelny 
1883bc1d29deSKrzysztof Grobelny         if (!success)
1884a6349918SAppaRao Puli         {
1885bc1d29deSKrzysztof Grobelny             messages::internalError(aResp->res);
1886bc1d29deSKrzysztof Grobelny             return;
1887a6349918SAppaRao Puli         }
1888a6349918SAppaRao Puli 
1889a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1890a6349918SAppaRao Puli         {
1891a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1892a6349918SAppaRao Puli             messages::internalError(aResp->res);
1893a6349918SAppaRao Puli             return;
1894a6349918SAppaRao Puli         }
1895a6349918SAppaRao Puli 
1896a6349918SAppaRao Puli         if (*provState == true)
1897a6349918SAppaRao Puli         {
1898a6349918SAppaRao Puli             if (*lockState == true)
1899a6349918SAppaRao Puli             {
1900a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1901a6349918SAppaRao Puli             }
1902a6349918SAppaRao Puli             else
1903a6349918SAppaRao Puli             {
1904a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1905a6349918SAppaRao Puli             }
1906a6349918SAppaRao Puli         }
1907a6349918SAppaRao Puli         else
1908a6349918SAppaRao Puli         {
1909a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1910a6349918SAppaRao Puli         }
1911bc1d29deSKrzysztof Grobelny         });
1912a6349918SAppaRao Puli }
1913a6349918SAppaRao Puli #endif
1914a6349918SAppaRao Puli 
1915491d8ee7SSantosh Puranik /**
19163a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
19173a2d0424SChris Cain  *
19183a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19193a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
19203a2d0424SChris Cain  *
19213a2d0424SChris Cain  * @return None.
19223a2d0424SChris Cain  */
19233a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19243a2d0424SChris Cain                                const std::string& modeValue)
19253a2d0424SChris Cain {
19260fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
19273a2d0424SChris Cain     {
19283a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
19293a2d0424SChris Cain     }
19300fda0f12SGeorge Liu     else if (
19310fda0f12SGeorge Liu         modeValue ==
19320fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
19333a2d0424SChris Cain     {
19343a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
19353a2d0424SChris Cain     }
19360fda0f12SGeorge Liu     else if (modeValue ==
19370fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
19383a2d0424SChris Cain     {
19393a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
19403a2d0424SChris Cain     }
19410fda0f12SGeorge Liu     else if (modeValue ==
19420fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
19433a2d0424SChris Cain     {
19443a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
19453a2d0424SChris Cain     }
19463a2d0424SChris Cain     else
19473a2d0424SChris Cain     {
19483a2d0424SChris Cain         // Any other values would be invalid
19493a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
19503a2d0424SChris Cain         messages::internalError(aResp->res);
19513a2d0424SChris Cain     }
19523a2d0424SChris Cain }
19533a2d0424SChris Cain 
19543a2d0424SChris Cain /**
19553a2d0424SChris Cain  * @brief Retrieves system power mode
19563a2d0424SChris Cain  *
19573a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19583a2d0424SChris Cain  *
19593a2d0424SChris Cain  * @return None.
19603a2d0424SChris Cain  */
19613a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
19623a2d0424SChris Cain {
19633a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
19643a2d0424SChris Cain 
19653a2d0424SChris Cain     // Get Power Mode object path:
1966e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1967e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
1968e99073f5SGeorge Liu     dbus::utility::getSubTree(
1969e99073f5SGeorge Liu         "/", 0, interfaces,
1970e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1971b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
19723a2d0424SChris Cain         if (ec)
19733a2d0424SChris Cain         {
1974002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1975002d39b4SEd Tanous                              << ec;
19763a2d0424SChris Cain             // This is an optional D-Bus object so just return if
19773a2d0424SChris Cain             // error occurs
19783a2d0424SChris Cain             return;
19793a2d0424SChris Cain         }
19803a2d0424SChris Cain         if (subtree.empty())
19813a2d0424SChris Cain         {
19823a2d0424SChris Cain             // As noted above, this is an optional interface so just return
19833a2d0424SChris Cain             // if there is no instance found
19843a2d0424SChris Cain             return;
19853a2d0424SChris Cain         }
19863a2d0424SChris Cain         if (subtree.size() > 1)
19873a2d0424SChris Cain         {
19883a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
19893a2d0424SChris Cain             // error
19903a2d0424SChris Cain             BMCWEB_LOG_DEBUG
19913a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
19923a2d0424SChris Cain                 << subtree.size();
19933a2d0424SChris Cain             messages::internalError(aResp->res);
19943a2d0424SChris Cain             return;
19953a2d0424SChris Cain         }
19963a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
19973a2d0424SChris Cain         {
19983a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
19993a2d0424SChris Cain             messages::internalError(aResp->res);
20003a2d0424SChris Cain             return;
20013a2d0424SChris Cain         }
20023a2d0424SChris Cain         const std::string& path = subtree[0].first;
20033a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
20043a2d0424SChris Cain         if (service.empty())
20053a2d0424SChris Cain         {
20063a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20073a2d0424SChris Cain             messages::internalError(aResp->res);
20083a2d0424SChris Cain             return;
20093a2d0424SChris Cain         }
20103a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
20111e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
20121e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
20131e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
20145e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
20151e1e598dSJonathan Doman                     const std::string& pmode) {
20168a592810SEd Tanous             if (ec2)
20173a2d0424SChris Cain             {
2018002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
20198a592810SEd Tanous                                  << ec2;
20203a2d0424SChris Cain                 messages::internalError(aResp->res);
20213a2d0424SChris Cain                 return;
20223a2d0424SChris Cain             }
20233a2d0424SChris Cain 
2024002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2025002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
20263a2d0424SChris Cain 
20271e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
20281e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
20291e1e598dSJonathan Doman             });
2030e99073f5SGeorge Liu         });
20313a2d0424SChris Cain }
20323a2d0424SChris Cain 
20333a2d0424SChris Cain /**
20343a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
20353a2d0424SChris Cain  * name associated with that string
20363a2d0424SChris Cain  *
20373a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20383a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
20393a2d0424SChris Cain  *
20403a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
20413a2d0424SChris Cain  */
20423a2d0424SChris Cain inline std::string
20433a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20443a2d0424SChris Cain                       const std::string& modeString)
20453a2d0424SChris Cain {
20463a2d0424SChris Cain     std::string mode;
20473a2d0424SChris Cain 
20483a2d0424SChris Cain     if (modeString == "Static")
20493a2d0424SChris Cain     {
20503a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
20513a2d0424SChris Cain     }
20523a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
20533a2d0424SChris Cain     {
20540fda0f12SGeorge Liu         mode =
20550fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
20563a2d0424SChris Cain     }
20573a2d0424SChris Cain     else if (modeString == "PowerSaving")
20583a2d0424SChris Cain     {
20593a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
20603a2d0424SChris Cain     }
20613a2d0424SChris Cain     else
20623a2d0424SChris Cain     {
20633a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
20643a2d0424SChris Cain     }
20653a2d0424SChris Cain     return mode;
20663a2d0424SChris Cain }
20673a2d0424SChris Cain 
20683a2d0424SChris Cain /**
20693a2d0424SChris Cain  * @brief Sets system power mode.
20703a2d0424SChris Cain  *
20713a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20723a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
20733a2d0424SChris Cain  *
20743a2d0424SChris Cain  * @return None.
20753a2d0424SChris Cain  */
20763a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20773a2d0424SChris Cain                          const std::string& pmode)
20783a2d0424SChris Cain {
20793a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
20803a2d0424SChris Cain 
20813a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
20823a2d0424SChris Cain     if (powerMode.empty())
20833a2d0424SChris Cain     {
20843a2d0424SChris Cain         return;
20853a2d0424SChris Cain     }
20863a2d0424SChris Cain 
20873a2d0424SChris Cain     // Get Power Mode object path:
2088e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2089e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2090e99073f5SGeorge Liu     dbus::utility::getSubTree(
2091e99073f5SGeorge Liu         "/", 0, interfaces,
2092b9d36b47SEd Tanous         [aResp,
2093e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2094b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
20953a2d0424SChris Cain         if (ec)
20963a2d0424SChris Cain         {
2097002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2098002d39b4SEd Tanous                              << ec;
20993a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21003a2d0424SChris Cain             messages::internalError(aResp->res);
21013a2d0424SChris Cain             return;
21023a2d0424SChris Cain         }
21033a2d0424SChris Cain         if (subtree.empty())
21043a2d0424SChris Cain         {
21053a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21063a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
21073a2d0424SChris Cain                                        "PowerMode");
21083a2d0424SChris Cain             return;
21093a2d0424SChris Cain         }
21103a2d0424SChris Cain         if (subtree.size() > 1)
21113a2d0424SChris Cain         {
21123a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21133a2d0424SChris Cain             // error
21143a2d0424SChris Cain             BMCWEB_LOG_DEBUG
21153a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
21163a2d0424SChris Cain                 << subtree.size();
21173a2d0424SChris Cain             messages::internalError(aResp->res);
21183a2d0424SChris Cain             return;
21193a2d0424SChris Cain         }
21203a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21213a2d0424SChris Cain         {
21223a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21233a2d0424SChris Cain             messages::internalError(aResp->res);
21243a2d0424SChris Cain             return;
21253a2d0424SChris Cain         }
21263a2d0424SChris Cain         const std::string& path = subtree[0].first;
21273a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21283a2d0424SChris Cain         if (service.empty())
21293a2d0424SChris Cain         {
21303a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21313a2d0424SChris Cain             messages::internalError(aResp->res);
21323a2d0424SChris Cain             return;
21333a2d0424SChris Cain         }
21343a2d0424SChris Cain 
21353a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
21363a2d0424SChris Cain                          << path;
21373a2d0424SChris Cain 
21383a2d0424SChris Cain         // Set the Power Mode property
21393a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
21405e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
21418a592810SEd Tanous             if (ec2)
21423a2d0424SChris Cain             {
21433a2d0424SChris Cain                 messages::internalError(aResp->res);
21443a2d0424SChris Cain                 return;
21453a2d0424SChris Cain             }
21463a2d0424SChris Cain             },
21473a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
21483a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2149168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
2150e99073f5SGeorge Liu         });
21513a2d0424SChris Cain }
21523a2d0424SChris Cain 
21533a2d0424SChris Cain /**
215451709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
215551709ffdSYong Li  *
215651709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
215751709ffdSYong Li  *
215851709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
215951709ffdSYong Li  * translation cannot be done, returns an empty string.
216051709ffdSYong Li  */
216123a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
216251709ffdSYong Li {
216351709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
216451709ffdSYong Li     {
216551709ffdSYong Li         return "None";
216651709ffdSYong Li     }
21673174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
216851709ffdSYong Li     {
216951709ffdSYong Li         return "ResetSystem";
217051709ffdSYong Li     }
21713174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
217251709ffdSYong Li     {
217351709ffdSYong Li         return "PowerDown";
217451709ffdSYong Li     }
21753174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
217651709ffdSYong Li     {
217751709ffdSYong Li         return "PowerCycle";
217851709ffdSYong Li     }
217951709ffdSYong Li 
218051709ffdSYong Li     return "";
218151709ffdSYong Li }
218251709ffdSYong Li 
218351709ffdSYong Li /**
2184c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2185c45f0082SYong Li  *
2186c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2187c45f0082SYong Li  *
2188c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2189c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2190c45f0082SYong Li  */
2191c45f0082SYong Li 
219223a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2193c45f0082SYong Li {
2194c45f0082SYong Li     if (rfAction == "None")
2195c45f0082SYong Li     {
2196c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2197c45f0082SYong Li     }
21983174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2199c45f0082SYong Li     {
2200c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2201c45f0082SYong Li     }
22023174e4dfSEd Tanous     if (rfAction == "PowerDown")
2203c45f0082SYong Li     {
2204c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2205c45f0082SYong Li     }
22063174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2207c45f0082SYong Li     {
2208c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2209c45f0082SYong Li     }
2210c45f0082SYong Li 
2211c45f0082SYong Li     return "";
2212c45f0082SYong Li }
2213c45f0082SYong Li 
2214c45f0082SYong Li /**
221551709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
221651709ffdSYong Li  *
221751709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
221851709ffdSYong Li  *
221951709ffdSYong Li  * @return None.
222051709ffdSYong Li  */
22218d1b46d7Szhanghch05 inline void
22228d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
222351709ffdSYong Li {
222451709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2225bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2226bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2227bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2228bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
22295e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
2230b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
223151709ffdSYong Li         if (ec)
223251709ffdSYong Li         {
223351709ffdSYong Li             // watchdog service is stopped
223451709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
223551709ffdSYong Li             return;
223651709ffdSYong Li         }
223751709ffdSYong Li 
223851709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
223951709ffdSYong Li 
224051709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
224151709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
224251709ffdSYong Li 
224351709ffdSYong Li         // watchdog service is running/enabled
224451709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
224551709ffdSYong Li 
2246bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2247bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
224851709ffdSYong Li 
2249bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2250bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2251bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2252bc1d29deSKrzysztof Grobelny 
2253bc1d29deSKrzysztof Grobelny         if (!success)
225451709ffdSYong Li         {
225551709ffdSYong Li             messages::internalError(aResp->res);
2256601af5edSChicago Duan             return;
225751709ffdSYong Li         }
225851709ffdSYong Li 
2259bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
226051709ffdSYong Li         {
2261bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
226251709ffdSYong Li         }
226351709ffdSYong Li 
2264bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2265bc1d29deSKrzysztof Grobelny         {
2266bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
226751709ffdSYong Li             if (action.empty())
226851709ffdSYong Li             {
226951709ffdSYong Li                 messages::internalError(aResp->res);
2270601af5edSChicago Duan                 return;
227151709ffdSYong Li             }
227251709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
227351709ffdSYong Li         }
2274bc1d29deSKrzysztof Grobelny         });
227551709ffdSYong Li }
227651709ffdSYong Li 
227751709ffdSYong Li /**
2278c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2279c45f0082SYong Li  *
2280c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2281c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2282c45f0082SYong Li  *                       RF request.
2283c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2284c45f0082SYong Li  *
2285c45f0082SYong Li  * @return None.
2286c45f0082SYong Li  */
22878d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2288c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2289c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2290c45f0082SYong Li {
2291c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2292c45f0082SYong Li 
2293c45f0082SYong Li     if (wdtTimeOutAction)
2294c45f0082SYong Li     {
2295c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2296c45f0082SYong Li         // check if TimeOut Action is Valid
2297c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2298c45f0082SYong Li         {
2299c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2300c45f0082SYong Li                              << *wdtTimeOutAction;
2301c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2302c45f0082SYong Li                                              "TimeoutAction");
2303c45f0082SYong Li             return;
2304c45f0082SYong Li         }
2305c45f0082SYong Li 
2306c45f0082SYong Li         crow::connections::systemBus->async_method_call(
23075e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2308c45f0082SYong Li             if (ec)
2309c45f0082SYong Li             {
2310c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2311c45f0082SYong Li                 messages::internalError(aResp->res);
2312c45f0082SYong Li                 return;
2313c45f0082SYong Li             }
2314c45f0082SYong Li             },
2315c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2316c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2317c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2318c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2319168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2320c45f0082SYong Li     }
2321c45f0082SYong Li 
2322c45f0082SYong Li     if (wdtEnable)
2323c45f0082SYong Li     {
2324c45f0082SYong Li         crow::connections::systemBus->async_method_call(
23255e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2326c45f0082SYong Li             if (ec)
2327c45f0082SYong Li             {
2328c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2329c45f0082SYong Li                 messages::internalError(aResp->res);
2330c45f0082SYong Li                 return;
2331c45f0082SYong Li             }
2332c45f0082SYong Li             },
2333c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2334c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2335c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2336c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2337168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2338c45f0082SYong Li     }
2339c45f0082SYong Li }
2340c45f0082SYong Li 
234137bbf98cSChris Cain /**
234237bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
234337bbf98cSChris Cain  *
234437bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
234537bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
234637bbf98cSChris Cain  *
234737bbf98cSChris Cain  * @return true if successful
234837bbf98cSChris Cain  */
23491e5b7c88SJiaqing Zhao inline bool
23501e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
23511e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
235237bbf98cSChris Cain {
2353bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2354bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2355bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2356bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2357bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2358bc1d29deSKrzysztof Grobelny 
2359bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2360bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2361*2661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2362*2661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2363*2661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2364bc1d29deSKrzysztof Grobelny 
2365bc1d29deSKrzysztof Grobelny     if (!success)
236637bbf98cSChris Cain     {
236737bbf98cSChris Cain         return false;
236837bbf98cSChris Cain     }
2369bc1d29deSKrzysztof Grobelny 
2370bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
237137bbf98cSChris Cain     {
2372bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
237337bbf98cSChris Cain     }
2374bc1d29deSKrzysztof Grobelny 
2375bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
237637bbf98cSChris Cain     {
2377bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2378bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
237937bbf98cSChris Cain     }
2380bc1d29deSKrzysztof Grobelny 
2381bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2382bc1d29deSKrzysztof Grobelny     {
2383bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
238437bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
238537bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
238637bbf98cSChris Cain                 .count();
238737bbf98cSChris Cain     }
2388bc1d29deSKrzysztof Grobelny 
2389bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
239037bbf98cSChris Cain     {
2391bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2392bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
239337bbf98cSChris Cain     }
2394bc1d29deSKrzysztof Grobelny 
2395bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
239637bbf98cSChris Cain     {
2397bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
239837bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
239937bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
240037bbf98cSChris Cain                 .count();
240137bbf98cSChris Cain     }
240237bbf98cSChris Cain 
240337bbf98cSChris Cain     return true;
240437bbf98cSChris Cain }
240537bbf98cSChris Cain 
240637bbf98cSChris Cain /**
240737bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
240837bbf98cSChris Cain  *
240937bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
241037bbf98cSChris Cain  *
241137bbf98cSChris Cain  * @return None.
241237bbf98cSChris Cain  */
241337bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
241437bbf98cSChris Cain {
241537bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
241637bbf98cSChris Cain 
241737bbf98cSChris Cain     // Get IdlePowerSaver object path:
2418e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2419e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2420e99073f5SGeorge Liu     dbus::utility::getSubTree(
2421e99073f5SGeorge Liu         "/", 0, interfaces,
2422e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2423b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
242437bbf98cSChris Cain         if (ec)
242537bbf98cSChris Cain         {
242637bbf98cSChris Cain             BMCWEB_LOG_DEBUG
242737bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
242837bbf98cSChris Cain                 << ec;
242937bbf98cSChris Cain             messages::internalError(aResp->res);
243037bbf98cSChris Cain             return;
243137bbf98cSChris Cain         }
243237bbf98cSChris Cain         if (subtree.empty())
243337bbf98cSChris Cain         {
243437bbf98cSChris Cain             // This is an optional interface so just return
243537bbf98cSChris Cain             // if there is no instance found
243637bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
243737bbf98cSChris Cain             return;
243837bbf98cSChris Cain         }
243937bbf98cSChris Cain         if (subtree.size() > 1)
244037bbf98cSChris Cain         {
244137bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
244237bbf98cSChris Cain             // is an error
244337bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
244437bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
244537bbf98cSChris Cain                              << subtree.size();
244637bbf98cSChris Cain             messages::internalError(aResp->res);
244737bbf98cSChris Cain             return;
244837bbf98cSChris Cain         }
244937bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
245037bbf98cSChris Cain         {
245137bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
245237bbf98cSChris Cain             messages::internalError(aResp->res);
245337bbf98cSChris Cain             return;
245437bbf98cSChris Cain         }
245537bbf98cSChris Cain         const std::string& path = subtree[0].first;
245637bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
245737bbf98cSChris Cain         if (service.empty())
245837bbf98cSChris Cain         {
2459002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
246037bbf98cSChris Cain             messages::internalError(aResp->res);
246137bbf98cSChris Cain             return;
246237bbf98cSChris Cain         }
246337bbf98cSChris Cain 
246437bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2465bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2466bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2467bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
24685e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
24691e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
24708a592810SEd Tanous             if (ec2)
247137bbf98cSChris Cain             {
247237bbf98cSChris Cain                 BMCWEB_LOG_ERROR
24738a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
247437bbf98cSChris Cain                 messages::internalError(aResp->res);
247537bbf98cSChris Cain                 return;
247637bbf98cSChris Cain             }
247737bbf98cSChris Cain 
2478e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
247937bbf98cSChris Cain             {
248037bbf98cSChris Cain                 messages::internalError(aResp->res);
248137bbf98cSChris Cain                 return;
248237bbf98cSChris Cain             }
2483bc1d29deSKrzysztof Grobelny             });
2484e99073f5SGeorge Liu         });
248537bbf98cSChris Cain 
248637bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
248737bbf98cSChris Cain }
248837bbf98cSChris Cain 
248937bbf98cSChris Cain /**
249037bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
249137bbf98cSChris Cain  *
249237bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
249337bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
249437bbf98cSChris Cain  *                       RF request.
249537bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
249637bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
249737bbf98cSChris Cain  * before entering idle state.
249837bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
249937bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
250037bbf98cSChris Cain  * before exiting idle state
250137bbf98cSChris Cain  *
250237bbf98cSChris Cain  * @return None.
250337bbf98cSChris Cain  */
250437bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
250537bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
250637bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
250737bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
250837bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
250937bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
251037bbf98cSChris Cain {
251137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
251237bbf98cSChris Cain 
251337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2514e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2515e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2516e99073f5SGeorge Liu     dbus::utility::getSubTree(
2517e99073f5SGeorge Liu         "/", 0, interfaces,
251837bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2519e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2520b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
252137bbf98cSChris Cain         if (ec)
252237bbf98cSChris Cain         {
252337bbf98cSChris Cain             BMCWEB_LOG_DEBUG
252437bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
252537bbf98cSChris Cain                 << ec;
252637bbf98cSChris Cain             messages::internalError(aResp->res);
252737bbf98cSChris Cain             return;
252837bbf98cSChris Cain         }
252937bbf98cSChris Cain         if (subtree.empty())
253037bbf98cSChris Cain         {
253137bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
253237bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
253337bbf98cSChris Cain                                        "IdlePowerSaver");
253437bbf98cSChris Cain             return;
253537bbf98cSChris Cain         }
253637bbf98cSChris Cain         if (subtree.size() > 1)
253737bbf98cSChris Cain         {
253837bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
253937bbf98cSChris Cain             // is an error
25400fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
25410fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
254237bbf98cSChris Cain                 << subtree.size();
254337bbf98cSChris Cain             messages::internalError(aResp->res);
254437bbf98cSChris Cain             return;
254537bbf98cSChris Cain         }
254637bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
254737bbf98cSChris Cain         {
254837bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
254937bbf98cSChris Cain             messages::internalError(aResp->res);
255037bbf98cSChris Cain             return;
255137bbf98cSChris Cain         }
255237bbf98cSChris Cain         const std::string& path = subtree[0].first;
255337bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
255437bbf98cSChris Cain         if (service.empty())
255537bbf98cSChris Cain         {
2556002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
255737bbf98cSChris Cain             messages::internalError(aResp->res);
255837bbf98cSChris Cain             return;
255937bbf98cSChris Cain         }
256037bbf98cSChris Cain 
256137bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
256237bbf98cSChris Cain         // need to be updated
256337bbf98cSChris Cain 
256437bbf98cSChris Cain         if (ipsEnable)
256537bbf98cSChris Cain         {
256637bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25675e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
25688a592810SEd Tanous                 if (ec2)
256937bbf98cSChris Cain                 {
25708a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
257137bbf98cSChris Cain                     messages::internalError(aResp->res);
257237bbf98cSChris Cain                     return;
257337bbf98cSChris Cain                 }
257437bbf98cSChris Cain                 },
257537bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2576002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2577002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
257837bbf98cSChris Cain         }
257937bbf98cSChris Cain         if (ipsEnterUtil)
258037bbf98cSChris Cain         {
258137bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25825e7e2dc5SEd 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                 "EnterUtilizationPercent",
2593168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
259437bbf98cSChris Cain         }
259537bbf98cSChris Cain         if (ipsEnterTime)
259637bbf98cSChris Cain         {
259737bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
259837bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
259937bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26005e7e2dc5SEd 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                 "EnterDwellTime",
2611168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
261237bbf98cSChris Cain         }
261337bbf98cSChris Cain         if (ipsExitUtil)
261437bbf98cSChris Cain         {
261537bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26165e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26178a592810SEd Tanous                 if (ec2)
261837bbf98cSChris Cain                 {
26198a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
262037bbf98cSChris Cain                     messages::internalError(aResp->res);
262137bbf98cSChris Cain                     return;
262237bbf98cSChris Cain                 }
262337bbf98cSChris Cain                 },
262437bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
262537bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
262637bbf98cSChris Cain                 "ExitUtilizationPercent",
2627168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
262837bbf98cSChris Cain         }
262937bbf98cSChris Cain         if (ipsExitTime)
263037bbf98cSChris Cain         {
263137bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
263237bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
263337bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26345e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26358a592810SEd Tanous                 if (ec2)
263637bbf98cSChris Cain                 {
26378a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
263837bbf98cSChris Cain                     messages::internalError(aResp->res);
263937bbf98cSChris Cain                     return;
264037bbf98cSChris Cain                 }
264137bbf98cSChris Cain                 },
264237bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
264337bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2644168e20c1SEd Tanous                 "ExitDwellTime",
2645168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
264637bbf98cSChris Cain         }
2647e99073f5SGeorge Liu         });
264837bbf98cSChris Cain 
264937bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
265037bbf98cSChris Cain }
265137bbf98cSChris Cain 
2652dd60b9edSEd Tanous inline void handleComputerSystemHead(
2653dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2654dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2655dd60b9edSEd Tanous {
2656dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2657dd60b9edSEd Tanous     {
2658dd60b9edSEd Tanous         return;
2659dd60b9edSEd Tanous     }
2660dd60b9edSEd Tanous     asyncResp->res.addHeader(
2661dd60b9edSEd Tanous         boost::beast::http::field::link,
2662dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2663dd60b9edSEd Tanous }
2664dd60b9edSEd Tanous 
2665c45f0082SYong Li /**
2666c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2667c5b2abe0SLewanczyk, Dawid  * Schema
2668c5b2abe0SLewanczyk, Dawid  */
26697e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
26701abe55efSEd Tanous {
26717e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2672dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2673dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2674dd60b9edSEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
2675dd60b9edSEd Tanous 
2676dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2677ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
26787e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2679f4c99e70SEd Tanous             [&app](const crow::Request& req,
26807e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
26813ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2682f4c99e70SEd Tanous         {
2683f4c99e70SEd Tanous             return;
2684f4c99e70SEd Tanous         }
2685dd60b9edSEd Tanous 
2686dd60b9edSEd Tanous         asyncResp->res.addHeader(
2687dd60b9edSEd Tanous             boost::beast::http::field::link,
2688dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
26898d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
26900f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
26918d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
26928d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2693462023adSSunitha Harish 
26941e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2695002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
26961e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2697002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
26985e7e2dc5SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
26991e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2700002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
27012c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2702002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
27031476687dSEd Tanous 
27041476687dSEd Tanous             nlohmann::json::object_t system;
27051476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
27061476687dSEd Tanous             ifaceArray.push_back(std::move(system));
270794bda602STim Lee             count = ifaceArray.size();
27088a592810SEd Tanous             if (!ec2)
2709462023adSSunitha Harish             {
2710462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
27111476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2712002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
27131476687dSEd Tanous                 ifaceArray.push_back(std::move(hypervisor));
27142c70f800SEd Tanous                 count = ifaceArray.size();
2715cb13a392SEd Tanous             }
27161e1e598dSJonathan Doman             });
27177e860f15SJohn Edward Broadbent         });
2718c5b2abe0SLewanczyk, Dawid }
27197e860f15SJohn Edward Broadbent 
27207e860f15SJohn Edward Broadbent /**
27217e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
27227e860f15SJohn Edward Broadbent  */
27234f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27247e860f15SJohn Edward Broadbent {
27257e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
27267e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
27277e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
27287e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
27297e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
27307e860f15SJohn Edward Broadbent 
27317e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
27325e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
27337e860f15SJohn Edward Broadbent         if (ec)
27347e860f15SJohn Edward Broadbent         {
27357e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
27367e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
27377e860f15SJohn Edward Broadbent             return;
27387e860f15SJohn Edward Broadbent         }
27397e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
27407e860f15SJohn Edward Broadbent         },
27417e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
27427e860f15SJohn Edward Broadbent }
2743c5b2abe0SLewanczyk, Dawid 
2744c5b2abe0SLewanczyk, Dawid /**
2745cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2746cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2747cc340dd9SEd Tanous  */
27487e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2749cc340dd9SEd Tanous {
2750cc340dd9SEd Tanous     /**
2751cc340dd9SEd Tanous      * Function handles POST method request.
2752cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2753cc340dd9SEd Tanous      */
27547e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
27557e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2756ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2757002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2758002d39b4SEd Tanous             [&app](const crow::Request& req,
27597e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27603ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
276145ca1b86SEd Tanous         {
276245ca1b86SEd Tanous             return;
276345ca1b86SEd Tanous         }
27649712f8acSEd Tanous         std::string resetType;
276515ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
27667e860f15SJohn Edward Broadbent                                        resetType))
2767cc340dd9SEd Tanous         {
2768cc340dd9SEd Tanous             return;
2769cc340dd9SEd Tanous         }
2770cc340dd9SEd Tanous 
2771d22c8396SJason M. Bills         // Get the command and host vs. chassis
2772cc340dd9SEd Tanous         std::string command;
2773543f4400SEd Tanous         bool hostCommand = true;
2774d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2775cc340dd9SEd Tanous         {
2776cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2777d22c8396SJason M. Bills             hostCommand = true;
2778d22c8396SJason M. Bills         }
2779d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2780d22c8396SJason M. Bills         {
2781d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2782d22c8396SJason M. Bills             hostCommand = false;
2783d22c8396SJason M. Bills         }
2784d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2785d22c8396SJason M. Bills         {
278686a0851aSJason M. Bills             command =
278786a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
278886a0851aSJason M. Bills             hostCommand = true;
2789cc340dd9SEd Tanous         }
27909712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2791cc340dd9SEd Tanous         {
2792cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2793d22c8396SJason M. Bills             hostCommand = true;
2794cc340dd9SEd Tanous         }
27959712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2796cc340dd9SEd Tanous         {
27970fda0f12SGeorge Liu             command =
27980fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2799d22c8396SJason M. Bills             hostCommand = true;
2800d22c8396SJason M. Bills         }
2801d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2802d22c8396SJason M. Bills         {
280386a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
280486a0851aSJason M. Bills             hostCommand = true;
2805cc340dd9SEd Tanous         }
2806bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2807bfd5b826SLakshminarayana R. Kammath         {
2808bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2809bfd5b826SLakshminarayana R. Kammath             return;
2810bfd5b826SLakshminarayana R. Kammath         }
2811cc340dd9SEd Tanous         else
2812cc340dd9SEd Tanous         {
28138d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
28148d1b46d7Szhanghch05                                              resetType);
2815cc340dd9SEd Tanous             return;
2816cc340dd9SEd Tanous         }
2817cc340dd9SEd Tanous 
2818d22c8396SJason M. Bills         if (hostCommand)
2819d22c8396SJason M. Bills         {
2820cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
28215e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2822cc340dd9SEd Tanous                 if (ec)
2823cc340dd9SEd Tanous                 {
2824cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2825002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2826d22c8396SJason M. Bills                     {
2827d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2828d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2829d22c8396SJason M. Bills                     }
2830d22c8396SJason M. Bills                     else
2831d22c8396SJason M. Bills                     {
2832f12894f8SJason M. Bills                         messages::internalError(asyncResp->res);
2833d22c8396SJason M. Bills                     }
2834cc340dd9SEd Tanous                     return;
2835cc340dd9SEd Tanous                 }
2836f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2837cc340dd9SEd Tanous                 },
2838cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2839cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2840cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
28419712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2842168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2843cc340dd9SEd Tanous         }
2844d22c8396SJason M. Bills         else
2845d22c8396SJason M. Bills         {
2846d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
28475e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2848d22c8396SJason M. Bills                 if (ec)
2849d22c8396SJason M. Bills                 {
2850d22c8396SJason M. Bills                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2851002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2852d22c8396SJason M. Bills                     {
2853d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2854d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2855d22c8396SJason M. Bills                     }
2856d22c8396SJason M. Bills                     else
2857d22c8396SJason M. Bills                     {
2858d22c8396SJason M. Bills                         messages::internalError(asyncResp->res);
2859d22c8396SJason M. Bills                     }
2860d22c8396SJason M. Bills                     return;
2861d22c8396SJason M. Bills                 }
2862d22c8396SJason M. Bills                 messages::success(asyncResp->res);
2863d22c8396SJason M. Bills                 },
2864d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
2865d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
2866d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
2867002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2868168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2869d22c8396SJason M. Bills         }
28707e860f15SJohn Edward Broadbent         });
2871d22c8396SJason M. Bills }
2872cc340dd9SEd Tanous 
287338c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead(
2874dd60b9edSEd Tanous     App& app, const crow::Request& req,
2875dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2876dd60b9edSEd Tanous {
2877dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2878dd60b9edSEd Tanous     {
2879dd60b9edSEd Tanous         return;
2880dd60b9edSEd Tanous     }
2881dd60b9edSEd Tanous 
2882dd60b9edSEd Tanous     asyncResp->res.addHeader(
2883dd60b9edSEd Tanous         boost::beast::http::field::link,
2884dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2885dd60b9edSEd Tanous }
2886dd60b9edSEd Tanous 
28875c3e9272SAbhishek Patel inline void afterPortRequest(
28885c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
28895c3e9272SAbhishek Patel     const boost::system::error_code& ec,
28905c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
28915c3e9272SAbhishek Patel {
28925c3e9272SAbhishek Patel     if (ec)
28935c3e9272SAbhishek Patel     {
28945c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
28955c3e9272SAbhishek Patel         return;
28965c3e9272SAbhishek Patel     }
28975c3e9272SAbhishek Patel     for (const auto& data : socketData)
28985c3e9272SAbhishek Patel     {
28995c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29005c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29015c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29025c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29035c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29045c3e9272SAbhishek Patel         // need to retrieve port number for
29055c3e9272SAbhishek Patel         // obmc-console-ssh service
29065c3e9272SAbhishek Patel         if (protocolName == "SSH")
29075c3e9272SAbhishek Patel         {
29085c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
29095c3e9272SAbhishek Patel                                           const boost::system::error_code ec1,
29105c3e9272SAbhishek Patel                                           int portNumber) {
29115c3e9272SAbhishek Patel                 if (ec1)
29125c3e9272SAbhishek Patel                 {
29135c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
29145c3e9272SAbhishek Patel                     return;
29155c3e9272SAbhishek Patel                 }
29165c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
29175c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
29185c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
29195c3e9272SAbhishek Patel             });
29205c3e9272SAbhishek Patel         }
29215c3e9272SAbhishek Patel     }
29225c3e9272SAbhishek Patel }
2923cc340dd9SEd Tanous /**
29246617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2925c5b2abe0SLewanczyk, Dawid  */
29267e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
29271abe55efSEd Tanous {
2928c5b2abe0SLewanczyk, Dawid 
2929dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2930dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystem)
2931dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2932dd60b9edSEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
2933c5b2abe0SLewanczyk, Dawid     /**
2934c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2935c5b2abe0SLewanczyk, Dawid      */
293622d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
2937ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
2938002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
2939002d39b4SEd Tanous             [&app](const crow::Request& req,
294022d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
294122d268cbSEd Tanous                    const std::string& systemName) {
29423ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
294345ca1b86SEd Tanous         {
294445ca1b86SEd Tanous             return;
294545ca1b86SEd Tanous         }
2946746b56f3SAsmitha Karunanithi 
2947746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
2948746b56f3SAsmitha Karunanithi         {
2949746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
2950746b56f3SAsmitha Karunanithi             return;
2951746b56f3SAsmitha Karunanithi         }
2952746b56f3SAsmitha Karunanithi 
295322d268cbSEd Tanous         if (systemName != "system")
295422d268cbSEd Tanous         {
295522d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
295622d268cbSEd Tanous                                        systemName);
295722d268cbSEd Tanous             return;
295822d268cbSEd Tanous         }
2959dd60b9edSEd Tanous         asyncResp->res.addHeader(
2960dd60b9edSEd Tanous             boost::beast::http::field::link,
2961dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
29628d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
296337bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
29648d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
29658d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
29668d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
29678d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
29688d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
29698d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
29708d1b46d7Szhanghch05             "Disabled";
29718d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
29728d1b46d7Szhanghch05             uint64_t(0);
29738d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
29748d1b46d7Szhanghch05             "Disabled";
2975002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
297604a258f4SEd Tanous 
29771476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
29781476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
29791476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
29801476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
29811476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
29821476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
29833179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
29843179105bSSunny Srivastava             "/redfish/v1/Systems/system/FabricAdapters";
2985029573d4SEd Tanous 
2986002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
29871476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
29881476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
29891476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
29901476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
2991c5b2abe0SLewanczyk, Dawid 
29921476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
29931476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
29941476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
29951476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
2996c4bf6374SJason M. Bills 
29971476687dSEd Tanous         nlohmann::json::array_t managedBy;
29981476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
29991476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3000002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
30011476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
30021476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
30030e8ac5e7SGunnar Mills 
30040e8ac5e7SGunnar Mills         // Fill in SerialConsole info
3005002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3006002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3007002d39b4SEd Tanous             true;
30081476687dSEd Tanous 
30090e8ac5e7SGunnar Mills         // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
30101476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
30111476687dSEd Tanous             true;
30121476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
30131476687dSEd Tanous         asyncResp->res
30141476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
30151476687dSEd Tanous             "Press ~. to exit console";
30165c3e9272SAbhishek Patel         getPortStatusAndPath(std::span{protocolToDBusForSystems},
30175c3e9272SAbhishek Patel                              std::bind_front(afterPortRequest, asyncResp));
30180e8ac5e7SGunnar Mills 
30190e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
30200e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3021002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3022002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3023002d39b4SEd Tanous             4;
3024613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3025613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
30261476687dSEd Tanous 
30270e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
30287a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3029b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
30302ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3031e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3032e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3033b49ac873SJames Feist 
3034b49ac873SJames Feist         auto health = std::make_shared<HealthPopulate>(asyncResp);
30357a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
30367a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
30377a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3038914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3039b49ac873SJames Feist             if (ec)
3040b49ac873SJames Feist             {
3041b49ac873SJames Feist                 // no inventory
3042b49ac873SJames Feist                 return;
3043b49ac873SJames Feist             }
3044b49ac873SJames Feist 
3045914e2d5dSEd Tanous             health->inventory = resp;
30467a1dbc48SGeorge Liu             });
3047b49ac873SJames Feist 
3048b49ac873SJames Feist         health->populate();
3049b49ac873SJames Feist 
3050002d39b4SEd Tanous         getMainChassisId(asyncResp,
3051002d39b4SEd Tanous                          [](const std::string& chassisId,
30528d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3053b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3054b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3055eddfc437SWilly Tu             chassis["@odata.id"] = crow::utility::urlFromPieces(
3056eddfc437SWilly Tu                 "redfish", "v1", "Chassis", chassisId);
3057002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3058c5d03ff4SJennifer Lee         });
3059a3002228SAppaRao Puli 
30609f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
30619f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3062a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
30635bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
30646c34de48SEd Tanous         getHostState(asyncResp);
3065491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
3066978b8803SAndrew Geissler         getBootProgress(asyncResp);
3067b6d5d45cSHieu Huynh         getBootProgressLastStateTime(asyncResp);
3068adbe192aSJason M. Bills         getPCIeDeviceList(asyncResp, "PCIeDevices");
306951709ffdSYong Li         getHostWatchdogTimer(asyncResp);
3070c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
30716bd5a8d2SGunnar Mills         getAutomaticRetry(asyncResp);
3072c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
3073a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3074a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
3075a6349918SAppaRao Puli #endif
30761981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
30773a2d0424SChris Cain         getPowerMode(asyncResp);
307837bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
30797e860f15SJohn Edward Broadbent         });
3080550a6bf8SJiaqing Zhao 
308122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3082ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
30837e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
308445ca1b86SEd Tanous             [&app](const crow::Request& req,
308522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
308622d268cbSEd Tanous                    const std::string& systemName) {
30873ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
308845ca1b86SEd Tanous         {
308945ca1b86SEd Tanous             return;
309045ca1b86SEd Tanous         }
309122d268cbSEd Tanous         if (systemName != "system")
309222d268cbSEd Tanous         {
309322d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
309422d268cbSEd Tanous                                        systemName);
309522d268cbSEd Tanous             return;
309622d268cbSEd Tanous         }
309722d268cbSEd Tanous 
3098dd60b9edSEd Tanous         asyncResp->res.addHeader(
3099dd60b9edSEd Tanous             boost::beast::http::field::link,
3100dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3101dd60b9edSEd Tanous 
31029f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
3103cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
310498e386ecSGunnar Mills         std::optional<std::string> assetTag;
3105c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
31063a2d0424SChris Cain         std::optional<std::string> powerMode;
3107550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
3108550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
3109550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
3110550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
3111550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
3112550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
3113550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
3114550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
3115550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
3116550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
3117550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
3118550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
3119550a6bf8SJiaqing Zhao 
3120550a6bf8SJiaqing Zhao         // clang-format off
312115ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3122550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3123550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
31247e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3125550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3126550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3127550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3128550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3129550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3130550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3131550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3132550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3133550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3134550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3135550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3136550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3137550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3138550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3139550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
31406617338dSEd Tanous                 {
31416617338dSEd Tanous                     return;
31426617338dSEd Tanous                 }
3143550a6bf8SJiaqing Zhao         // clang-format on
3144491d8ee7SSantosh Puranik 
31458d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3146c45f0082SYong Li 
314798e386ecSGunnar Mills         if (assetTag)
314898e386ecSGunnar Mills         {
314998e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
315098e386ecSGunnar Mills         }
315198e386ecSGunnar Mills 
3152550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3153c45f0082SYong Li         {
3154f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3155c45f0082SYong Li         }
3156c45f0082SYong Li 
3157cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
315869f35306SGunnar Mills         {
3159002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3160491d8ee7SSantosh Puranik         }
3161550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
316269f35306SGunnar Mills         {
3163550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
316469f35306SGunnar Mills         }
3165ac7e1e0bSAli Ahmed 
3166550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3167ac7e1e0bSAli Ahmed         {
3168550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3169550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
317069f35306SGunnar Mills         }
3171265c1602SJohnathan Mantey 
31729f8bfa7cSGunnar Mills         if (locationIndicatorActive)
31739f8bfa7cSGunnar Mills         {
3174002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
31759f8bfa7cSGunnar Mills         }
31769f8bfa7cSGunnar Mills 
31777e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
31787e860f15SJohn Edward Broadbent         // passed
31799712f8acSEd Tanous         if (indicatorLed)
31806617338dSEd Tanous         {
3181f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3182002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3183d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3184d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
31856617338dSEd Tanous         }
3186c6a620f2SGeorge Liu 
3187c6a620f2SGeorge Liu         if (powerRestorePolicy)
3188c6a620f2SGeorge Liu         {
31894e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3190c6a620f2SGeorge Liu         }
31913a2d0424SChris Cain 
31923a2d0424SChris Cain         if (powerMode)
31933a2d0424SChris Cain         {
31943a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
31953a2d0424SChris Cain         }
319637bbf98cSChris Cain 
3197550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3198550a6bf8SJiaqing Zhao             ipsExitTime)
319937bbf98cSChris Cain         {
3200002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3201002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
320237bbf98cSChris Cain         }
32037e860f15SJohn Edward Broadbent         });
3204c5b2abe0SLewanczyk, Dawid }
32051cb1a9e6SAppaRao Puli 
320638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3207dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
3208dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3209dd60b9edSEd Tanous {
3210dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3211dd60b9edSEd Tanous     {
3212dd60b9edSEd Tanous         return;
3213dd60b9edSEd Tanous     }
3214dd60b9edSEd Tanous     asyncResp->res.addHeader(
3215dd60b9edSEd Tanous         boost::beast::http::field::link,
3216dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3217dd60b9edSEd Tanous }
3218dd60b9edSEd Tanous 
32191cb1a9e6SAppaRao Puli /**
32201cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
32211cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
32221cb1a9e6SAppaRao Puli  */
32237e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
32241cb1a9e6SAppaRao Puli {
3225dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3226dd60b9edSEd Tanous         .privileges(redfish::privileges::headActionInfo)
3227dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3228dd60b9edSEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
32291cb1a9e6SAppaRao Puli     /**
32301cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
32311cb1a9e6SAppaRao Puli      */
323222d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3233ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
32347e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
323545ca1b86SEd Tanous             [&app](const crow::Request& req,
323622d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
323722d268cbSEd Tanous                    const std::string& systemName) {
32383ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
323945ca1b86SEd Tanous         {
324045ca1b86SEd Tanous             return;
324145ca1b86SEd Tanous         }
3242746b56f3SAsmitha Karunanithi 
3243746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3244746b56f3SAsmitha Karunanithi         {
3245746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3246746b56f3SAsmitha Karunanithi             return;
3247746b56f3SAsmitha Karunanithi         }
3248746b56f3SAsmitha Karunanithi 
324922d268cbSEd Tanous         if (systemName != "system")
325022d268cbSEd Tanous         {
325122d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
325222d268cbSEd Tanous                                        systemName);
325322d268cbSEd Tanous             return;
325422d268cbSEd Tanous         }
325522d268cbSEd Tanous 
3256dd60b9edSEd Tanous         asyncResp->res.addHeader(
3257dd60b9edSEd Tanous             boost::beast::http::field::link,
3258dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
32591476687dSEd Tanous 
32601476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
32611476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
32621476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
32631476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
32641476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
32651476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
32663215e700SNan Zhou 
32673215e700SNan Zhou         nlohmann::json::array_t parameters;
32683215e700SNan Zhou         nlohmann::json::object_t parameter;
32693215e700SNan Zhou 
32703215e700SNan Zhou         parameter["Name"] = "ResetType";
32713215e700SNan Zhou         parameter["Required"] = true;
32723215e700SNan Zhou         parameter["DataType"] = "String";
32733215e700SNan Zhou         nlohmann::json::array_t allowableValues;
32743215e700SNan Zhou         allowableValues.emplace_back("On");
32753215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
32763215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
32773215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
32783215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
32793215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
32803215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
32813215e700SNan Zhou         allowableValues.emplace_back("Nmi");
32823215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
32833215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
32843215e700SNan Zhou 
32853215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
32867e860f15SJohn Edward Broadbent         });
32871cb1a9e6SAppaRao Puli }
3288c5b2abe0SLewanczyk, Dawid } // namespace redfish
3289