xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 797d5dae9eed4e783d065be24f5ac0bf4ffe1a1a)
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 /**
1153*797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1154*797d5daeSCorey Hardesty  *
1155*797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1156*797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1157*797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1158*797d5daeSCorey Hardesty  * dbus.
1159*797d5daeSCorey Hardesty  *
1160*797d5daeSCorey Hardesty  * @param[in] aResp     Shared pointer for generating response message.
1161*797d5daeSCorey Hardesty  *
1162*797d5daeSCorey Hardesty  * @return None.
1163*797d5daeSCorey Hardesty  */
1164*797d5daeSCorey Hardesty inline void
1165*797d5daeSCorey Hardesty     getAutomaticRebootAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1166*797d5daeSCorey Hardesty {
1167*797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1168*797d5daeSCorey Hardesty 
1169*797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1170*797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1171*797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1172*797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1173*797d5daeSCorey Hardesty         [aResp{aResp}](const boost::system::error_code& ec,
1174*797d5daeSCorey Hardesty                        const dbus::utility::DBusPropertiesMap& propertiesList) {
1175*797d5daeSCorey Hardesty         if (ec)
1176*797d5daeSCorey Hardesty         {
1177*797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1178*797d5daeSCorey Hardesty             {
1179*797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1180*797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1181*797d5daeSCorey Hardesty             }
1182*797d5daeSCorey Hardesty             return;
1183*797d5daeSCorey Hardesty         }
1184*797d5daeSCorey Hardesty 
1185*797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1186*797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1187*797d5daeSCorey Hardesty 
1188*797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1189*797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1190*797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1191*797d5daeSCorey Hardesty 
1192*797d5daeSCorey Hardesty         if (!success)
1193*797d5daeSCorey Hardesty         {
1194*797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1195*797d5daeSCorey Hardesty             return;
1196*797d5daeSCorey Hardesty         }
1197*797d5daeSCorey Hardesty 
1198*797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1199*797d5daeSCorey Hardesty         {
1200*797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1201*797d5daeSCorey Hardesty                 *attemptsLeft;
1202*797d5daeSCorey Hardesty         }
1203*797d5daeSCorey Hardesty 
1204*797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1205*797d5daeSCorey Hardesty         {
1206*797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1207*797d5daeSCorey Hardesty                 *retryAttempts;
1208*797d5daeSCorey Hardesty         }
1209*797d5daeSCorey Hardesty         });
1210*797d5daeSCorey Hardesty }
1211*797d5daeSCorey Hardesty 
1212*797d5daeSCorey Hardesty /**
12136bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12146bd5a8d2SGunnar Mills  *
12156bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
12166bd5a8d2SGunnar Mills  *
12176bd5a8d2SGunnar Mills  * @return None.
12186bd5a8d2SGunnar Mills  */
1219*797d5daeSCorey Hardesty inline void
1220*797d5daeSCorey Hardesty     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12216bd5a8d2SGunnar Mills {
12226bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12236bd5a8d2SGunnar Mills 
12241e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12251e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12261e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12271e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
12285e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) {
12296bd5a8d2SGunnar Mills         if (ec)
12306bd5a8d2SGunnar Mills         {
1231*797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1232*797d5daeSCorey Hardesty             {
1233*797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1234*797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1235*797d5daeSCorey Hardesty             }
12366bd5a8d2SGunnar Mills             return;
12376bd5a8d2SGunnar Mills         }
12386bd5a8d2SGunnar Mills 
12391e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1240e05aec50SEd Tanous         if (autoRebootEnabled)
12416bd5a8d2SGunnar Mills         {
12426bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12436bd5a8d2SGunnar Mills                 "RetryAttempts";
12446bd5a8d2SGunnar Mills         }
12456bd5a8d2SGunnar Mills         else
12466bd5a8d2SGunnar Mills         {
1247002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
12486bd5a8d2SGunnar Mills         }
1249*797d5daeSCorey Hardesty         getAutomaticRebootAttempts(aResp);
125069f35306SGunnar Mills 
125169f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
125269f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
125369f35306SGunnar Mills         // RetryAttempts.
1254002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
12550fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
12560fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
12571e1e598dSJonathan Doman         });
12586bd5a8d2SGunnar Mills }
12596bd5a8d2SGunnar Mills 
12606bd5a8d2SGunnar Mills /**
1261*797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1262*797d5daeSCorey Hardesty  *
1263*797d5daeSCorey Hardesty  * @param[in] aResp   Shared pointer for generating response message.
1264*797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1265*797d5daeSCorey Hardesty  *
1266*797d5daeSCorey Hardesty  *@return None.
1267*797d5daeSCorey Hardesty  */
1268*797d5daeSCorey Hardesty 
1269*797d5daeSCorey Hardesty inline void
1270*797d5daeSCorey Hardesty     setAutomaticRetryAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1271*797d5daeSCorey Hardesty                               const uint32_t retryAttempts)
1272*797d5daeSCorey Hardesty {
1273*797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
1274*797d5daeSCorey Hardesty     crow::connections::systemBus->async_method_call(
1275*797d5daeSCorey Hardesty         [aResp](const boost::system::error_code& ec) {
1276*797d5daeSCorey Hardesty         if (ec)
1277*797d5daeSCorey Hardesty         {
1278*797d5daeSCorey Hardesty             BMCWEB_LOG_ERROR
1279*797d5daeSCorey Hardesty                 << "DBUS response error: Set setAutomaticRetryAttempts" << ec;
1280*797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1281*797d5daeSCorey Hardesty             return;
1282*797d5daeSCorey Hardesty         }
1283*797d5daeSCorey Hardesty         },
1284*797d5daeSCorey Hardesty         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1285*797d5daeSCorey Hardesty         "org.freedesktop.DBus.Properties", "Set",
1286*797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1287*797d5daeSCorey Hardesty         std::variant<uint32_t>(retryAttempts));
1288*797d5daeSCorey Hardesty }
1289*797d5daeSCorey Hardesty 
1290*797d5daeSCorey Hardesty /**
1291c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1292c6a620f2SGeorge Liu  *
1293c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1294c6a620f2SGeorge Liu  *
1295c6a620f2SGeorge Liu  * @return None.
1296c6a620f2SGeorge Liu  */
12978d1b46d7Szhanghch05 inline void
12988d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1299c6a620f2SGeorge Liu {
1300c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1301c6a620f2SGeorge Liu 
13021e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13031e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13041e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13051e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
13065e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
13075e7e2dc5SEd Tanous                 const std::string& policy) {
1308c6a620f2SGeorge Liu         if (ec)
1309c6a620f2SGeorge Liu         {
1310c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1311c6a620f2SGeorge Liu             return;
1312c6a620f2SGeorge Liu         }
1313c6a620f2SGeorge Liu 
13140fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
13150fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1316c6a620f2SGeorge Liu              "AlwaysOn"},
13170fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1318c6a620f2SGeorge Liu              "AlwaysOff"},
13190fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
13204ed47cb8SMatthew Barth              "LastState"},
13214ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
13224ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
13234ed47cb8SMatthew Barth              "AlwaysOff"}};
1324c6a620f2SGeorge Liu 
13251e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1326c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1327c6a620f2SGeorge Liu         {
1328c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1329c6a620f2SGeorge Liu             return;
1330c6a620f2SGeorge Liu         }
1331c6a620f2SGeorge Liu 
1332c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
13331e1e598dSJonathan Doman         });
1334c6a620f2SGeorge Liu }
1335c6a620f2SGeorge Liu 
1336c6a620f2SGeorge Liu /**
13371981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13381981771bSAli Ahmed  * TPM is required for booting the host.
13391981771bSAli Ahmed  *
13401981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13411981771bSAli Ahmed  *
13421981771bSAli Ahmed  * @return None.
13431981771bSAli Ahmed  */
13441981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13451981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13461981771bSAli Ahmed {
13471981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1348e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1349e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1350e99073f5SGeorge Liu     dbus::utility::getSubTree(
1351e99073f5SGeorge Liu         "/", 0, interfaces,
1352e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1353b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
13541981771bSAli Ahmed         if (ec)
13551981771bSAli Ahmed         {
1356002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1357002d39b4SEd Tanous                              << ec;
13581981771bSAli Ahmed             // This is an optional D-Bus object so just return if
13591981771bSAli Ahmed             // error occurs
13601981771bSAli Ahmed             return;
13611981771bSAli Ahmed         }
136226f6976fSEd Tanous         if (subtree.empty())
13631981771bSAli Ahmed         {
13641981771bSAli Ahmed             // As noted above, this is an optional interface so just return
13651981771bSAli Ahmed             // if there is no instance found
13661981771bSAli Ahmed             return;
13671981771bSAli Ahmed         }
13681981771bSAli Ahmed 
13691981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
13701981771bSAli Ahmed         if (subtree.size() > 1)
13711981771bSAli Ahmed         {
13721981771bSAli Ahmed             BMCWEB_LOG_DEBUG
13731981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13741981771bSAli Ahmed                 << subtree.size();
13751981771bSAli Ahmed             // Throw an internal Error and return
13761981771bSAli Ahmed             messages::internalError(aResp->res);
13771981771bSAli Ahmed             return;
13781981771bSAli Ahmed         }
13791981771bSAli Ahmed 
13801981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13811981771bSAli Ahmed         // field
13821981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13831981771bSAli Ahmed         {
13841981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13851981771bSAli Ahmed             messages::internalError(aResp->res);
13861981771bSAli Ahmed             return;
13871981771bSAli Ahmed         }
13881981771bSAli Ahmed 
13891981771bSAli Ahmed         const std::string& path = subtree[0].first;
13901981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
13911981771bSAli Ahmed 
13921981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
13931e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
13941e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
13951e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
13965e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
13978a592810SEd Tanous             if (ec2)
13981981771bSAli Ahmed             {
1399002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
14008a592810SEd Tanous                                  << ec2;
14011981771bSAli Ahmed                 messages::internalError(aResp->res);
14021981771bSAli Ahmed                 return;
14031981771bSAli Ahmed             }
14041981771bSAli Ahmed 
14051e1e598dSJonathan Doman             if (tpmRequired)
14061981771bSAli Ahmed             {
1407002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14081981771bSAli Ahmed                     "Required";
14091981771bSAli Ahmed             }
14101981771bSAli Ahmed             else
14111981771bSAli Ahmed             {
1412002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14131981771bSAli Ahmed                     "Disabled";
14141981771bSAli Ahmed             }
14151e1e598dSJonathan Doman             });
1416e99073f5SGeorge Liu         });
14171981771bSAli Ahmed }
14181981771bSAli Ahmed 
14191981771bSAli Ahmed /**
14201c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14211c05dae3SAli Ahmed  * TPM is required for booting the host.
14221c05dae3SAli Ahmed  *
14231c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
14241c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14251c05dae3SAli Ahmed  *
14261c05dae3SAli Ahmed  * @return None.
14271c05dae3SAli Ahmed  */
14281c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
14291c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
14301c05dae3SAli Ahmed {
14311c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1432e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1433e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1434e99073f5SGeorge Liu     dbus::utility::getSubTree(
1435e99073f5SGeorge Liu         "/", 0, interfaces,
1436e99073f5SGeorge Liu         [aResp,
1437e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1438e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14391c05dae3SAli Ahmed         if (ec)
14401c05dae3SAli Ahmed         {
1441002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1442002d39b4SEd Tanous                              << ec;
14431c05dae3SAli Ahmed             messages::internalError(aResp->res);
14441c05dae3SAli Ahmed             return;
14451c05dae3SAli Ahmed         }
144626f6976fSEd Tanous         if (subtree.empty())
14471c05dae3SAli Ahmed         {
14481c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
14491c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
14501c05dae3SAli Ahmed             return;
14511c05dae3SAli Ahmed         }
14521c05dae3SAli Ahmed 
14531c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
14541c05dae3SAli Ahmed         if (subtree.size() > 1)
14551c05dae3SAli Ahmed         {
14561c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
14571c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
14581c05dae3SAli Ahmed                 << subtree.size();
14591c05dae3SAli Ahmed             // Throw an internal Error and return
14601c05dae3SAli Ahmed             messages::internalError(aResp->res);
14611c05dae3SAli Ahmed             return;
14621c05dae3SAli Ahmed         }
14631c05dae3SAli Ahmed 
14641c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14651c05dae3SAli Ahmed         // field
14661c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14671c05dae3SAli Ahmed         {
14681c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14691c05dae3SAli Ahmed             messages::internalError(aResp->res);
14701c05dae3SAli Ahmed             return;
14711c05dae3SAli Ahmed         }
14721c05dae3SAli Ahmed 
14731c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
14741c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14751c05dae3SAli Ahmed 
14761c05dae3SAli Ahmed         if (serv.empty())
14771c05dae3SAli Ahmed         {
14781c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
14791c05dae3SAli Ahmed             messages::internalError(aResp->res);
14801c05dae3SAli Ahmed             return;
14811c05dae3SAli Ahmed         }
14821c05dae3SAli Ahmed 
14831c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
14841c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
14855e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
14868a592810SEd Tanous             if (ec2)
14871c05dae3SAli Ahmed             {
14880fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
14890fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
14908a592810SEd Tanous                     << ec2;
14911c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14921c05dae3SAli Ahmed                 return;
14931c05dae3SAli Ahmed             }
14941c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
14951c05dae3SAli Ahmed             },
14961c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
14971c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1498168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
1499e99073f5SGeorge Liu         });
15001c05dae3SAli Ahmed }
15011c05dae3SAli Ahmed 
15021c05dae3SAli Ahmed /**
1503491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1504491d8ee7SSantosh Puranik  *
1505491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1506cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1507cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1508cd9a4666SKonstantin Aladyshev  */
1509cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1510cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1511cd9a4666SKonstantin Aladyshev {
1512c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1513cd9a4666SKonstantin Aladyshev 
1514c21865c4SKonstantin Aladyshev     if (!bootType)
1515cd9a4666SKonstantin Aladyshev     {
1516c21865c4SKonstantin Aladyshev         return;
1517c21865c4SKonstantin Aladyshev     }
1518c21865c4SKonstantin Aladyshev 
1519cd9a4666SKonstantin Aladyshev     // Source target specified
1520cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1521cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1522cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1523cd9a4666SKonstantin Aladyshev     {
1524cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1525cd9a4666SKonstantin Aladyshev     }
1526cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1527cd9a4666SKonstantin Aladyshev     {
1528cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1529cd9a4666SKonstantin Aladyshev     }
1530cd9a4666SKonstantin Aladyshev     else
1531cd9a4666SKonstantin Aladyshev     {
1532cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1533cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1534cd9a4666SKonstantin Aladyshev                          << *bootType;
1535cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1536cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1537cd9a4666SKonstantin Aladyshev         return;
1538cd9a4666SKonstantin Aladyshev     }
1539cd9a4666SKonstantin Aladyshev 
1540cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1541cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1542cd9a4666SKonstantin Aladyshev 
1543cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
15445e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1545cd9a4666SKonstantin Aladyshev         if (ec)
1546cd9a4666SKonstantin Aladyshev         {
1547cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1548cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1549cd9a4666SKonstantin Aladyshev             {
1550cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1551cd9a4666SKonstantin Aladyshev                 return;
1552cd9a4666SKonstantin Aladyshev             }
1553cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1554cd9a4666SKonstantin Aladyshev             return;
1555cd9a4666SKonstantin Aladyshev         }
1556cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1557cd9a4666SKonstantin Aladyshev         },
1558c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1559c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1560cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1561cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1562168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1563cd9a4666SKonstantin Aladyshev }
1564cd9a4666SKonstantin Aladyshev 
1565cd9a4666SKonstantin Aladyshev /**
1566cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1567cd9a4666SKonstantin Aladyshev  *
1568cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1569c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1570c21865c4SKonstantin Aladyshev  * @return Integer error code.
1571c21865c4SKonstantin Aladyshev  */
1572c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1573c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1574c21865c4SKonstantin Aladyshev {
1575c21865c4SKonstantin Aladyshev     if (!bootEnable)
1576c21865c4SKonstantin Aladyshev     {
1577c21865c4SKonstantin Aladyshev         return;
1578c21865c4SKonstantin Aladyshev     }
1579c21865c4SKonstantin Aladyshev     // Source target specified
1580c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1581c21865c4SKonstantin Aladyshev 
1582c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1583c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1584c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1585c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1586c21865c4SKonstantin Aladyshev     {
1587c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1588c21865c4SKonstantin Aladyshev     }
1589c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1590c21865c4SKonstantin Aladyshev     {
1591c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1592c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1593c21865c4SKonstantin Aladyshev     }
1594c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1595c21865c4SKonstantin Aladyshev     {
1596c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1597c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1598c21865c4SKonstantin Aladyshev     }
1599c21865c4SKonstantin Aladyshev     else
1600c21865c4SKonstantin Aladyshev     {
16010fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
16020fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1603c21865c4SKonstantin Aladyshev             << *bootEnable;
1604c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1605c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1606c21865c4SKonstantin Aladyshev         return;
1607c21865c4SKonstantin Aladyshev     }
1608c21865c4SKonstantin Aladyshev 
1609c21865c4SKonstantin Aladyshev     // Act on validated parameters
1610c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1611c21865c4SKonstantin Aladyshev 
1612c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16135e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec2) {
16148a592810SEd Tanous         if (ec2)
1615c21865c4SKonstantin Aladyshev         {
16168a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1617c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1618c21865c4SKonstantin Aladyshev             return;
1619c21865c4SKonstantin Aladyshev         }
1620c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1621c21865c4SKonstantin Aladyshev         },
1622c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1623c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1624c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1625c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1626168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1627c21865c4SKonstantin Aladyshev 
1628c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1629c21865c4SKonstantin Aladyshev     {
1630c21865c4SKonstantin Aladyshev         return;
1631c21865c4SKonstantin Aladyshev     }
1632c21865c4SKonstantin Aladyshev 
1633c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1634c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1635c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1636c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1637c21865c4SKonstantin Aladyshev 
1638c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16395e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1640c21865c4SKonstantin Aladyshev         if (ec)
1641c21865c4SKonstantin Aladyshev         {
1642c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1643c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1644c21865c4SKonstantin Aladyshev             return;
1645c21865c4SKonstantin Aladyshev         }
1646c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1647c21865c4SKonstantin Aladyshev         },
1648c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1649c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1650c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1651c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1652168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1653c21865c4SKonstantin Aladyshev }
1654c21865c4SKonstantin Aladyshev 
1655c21865c4SKonstantin Aladyshev /**
1656c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1657c21865c4SKonstantin Aladyshev  *
1658c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1659491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1660491d8ee7SSantosh Puranik  *
1661265c1602SJohnathan Mantey  * @return Integer error code.
1662491d8ee7SSantosh Puranik  */
1663cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1664cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1665491d8ee7SSantosh Puranik {
1666c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1667c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1668944ffaf9SJohnathan Mantey 
1669c21865c4SKonstantin Aladyshev     if (!bootSource)
1670491d8ee7SSantosh Puranik     {
1671c21865c4SKonstantin Aladyshev         return;
1672c21865c4SKonstantin Aladyshev     }
1673c21865c4SKonstantin Aladyshev 
1674491d8ee7SSantosh Puranik     // Source target specified
1675491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1676491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1677e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1678e662eae8SEd Tanous         0)
1679491d8ee7SSantosh Puranik     {
1680944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1681944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1682491d8ee7SSantosh Puranik             << *bootSource;
1683491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1684491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1685491d8ee7SSantosh Puranik         return;
1686491d8ee7SSantosh Puranik     }
1687491d8ee7SSantosh Puranik 
1688944ffaf9SJohnathan Mantey     // Act on validated parameters
1689944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1690944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1691944ffaf9SJohnathan Mantey 
1692491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
16935e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1694491d8ee7SSantosh Puranik         if (ec)
1695491d8ee7SSantosh Puranik         {
1696491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1697491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1698491d8ee7SSantosh Puranik             return;
1699491d8ee7SSantosh Puranik         }
1700491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1701491d8ee7SSantosh Puranik         },
1702c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1703c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1704491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1705491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1706168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1707944ffaf9SJohnathan Mantey 
1708491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
17095e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1710491d8ee7SSantosh Puranik         if (ec)
1711491d8ee7SSantosh Puranik         {
1712491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1713491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1714491d8ee7SSantosh Puranik             return;
1715491d8ee7SSantosh Puranik         }
1716491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1717491d8ee7SSantosh Puranik         },
1718c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1719c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1720491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1721491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1722168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1723cd9a4666SKonstantin Aladyshev }
1724944ffaf9SJohnathan Mantey 
1725cd9a4666SKonstantin Aladyshev /**
1726c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1727491d8ee7SSantosh Puranik  *
1728491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1729491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1730cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1731491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1732491d8ee7SSantosh Puranik  *
1733265c1602SJohnathan Mantey  * @return Integer error code.
1734491d8ee7SSantosh Puranik  */
1735c21865c4SKonstantin Aladyshev 
1736c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1737c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1738c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1739c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1740491d8ee7SSantosh Puranik {
1741491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1742491d8ee7SSantosh Puranik 
1743c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1744c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1745c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1746491d8ee7SSantosh Puranik }
1747491d8ee7SSantosh Puranik 
1748c6a620f2SGeorge Liu /**
174998e386ecSGunnar Mills  * @brief Sets AssetTag
175098e386ecSGunnar Mills  *
175198e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
175298e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
175398e386ecSGunnar Mills  *
175498e386ecSGunnar Mills  * @return None.
175598e386ecSGunnar Mills  */
17568d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
175798e386ecSGunnar Mills                         const std::string& assetTag)
175898e386ecSGunnar Mills {
1759e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1760e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1761e99073f5SGeorge Liu     dbus::utility::getSubTree(
1762e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1763b9d36b47SEd Tanous         [aResp,
1764e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1765b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
176698e386ecSGunnar Mills         if (ec)
176798e386ecSGunnar Mills         {
176898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
176998e386ecSGunnar Mills             messages::internalError(aResp->res);
177098e386ecSGunnar Mills             return;
177198e386ecSGunnar Mills         }
177226f6976fSEd Tanous         if (subtree.empty())
177398e386ecSGunnar Mills         {
177498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
177598e386ecSGunnar Mills             messages::internalError(aResp->res);
177698e386ecSGunnar Mills             return;
177798e386ecSGunnar Mills         }
177898e386ecSGunnar Mills         // Assume only 1 system D-Bus object
177998e386ecSGunnar Mills         // Throw an error if there is more than 1
178098e386ecSGunnar Mills         if (subtree.size() > 1)
178198e386ecSGunnar Mills         {
178298e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
178398e386ecSGunnar Mills             messages::internalError(aResp->res);
178498e386ecSGunnar Mills             return;
178598e386ecSGunnar Mills         }
178698e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
178798e386ecSGunnar Mills         {
178898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
178998e386ecSGunnar Mills             messages::internalError(aResp->res);
179098e386ecSGunnar Mills             return;
179198e386ecSGunnar Mills         }
179298e386ecSGunnar Mills 
179398e386ecSGunnar Mills         const std::string& path = subtree[0].first;
179498e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
179598e386ecSGunnar Mills 
179698e386ecSGunnar Mills         if (service.empty())
179798e386ecSGunnar Mills         {
179898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
179998e386ecSGunnar Mills             messages::internalError(aResp->res);
180098e386ecSGunnar Mills             return;
180198e386ecSGunnar Mills         }
180298e386ecSGunnar Mills 
180398e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
18045e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
180598e386ecSGunnar Mills             if (ec2)
180698e386ecSGunnar Mills             {
1807002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1808002d39b4SEd Tanous                                  << ec2;
180998e386ecSGunnar Mills                 messages::internalError(aResp->res);
181098e386ecSGunnar Mills                 return;
181198e386ecSGunnar Mills             }
181298e386ecSGunnar Mills             },
181398e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
181498e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1815168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
1816e99073f5SGeorge Liu         });
181798e386ecSGunnar Mills }
181898e386ecSGunnar Mills 
181998e386ecSGunnar Mills /**
182069f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
182169f35306SGunnar Mills  *
182269f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
182369f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
182469f35306SGunnar Mills  *
182569f35306SGunnar Mills  * @return None.
182669f35306SGunnar Mills  */
18278d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1828f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
182969f35306SGunnar Mills {
183069f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
183169f35306SGunnar Mills 
183269f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1833543f4400SEd Tanous     bool autoRebootEnabled = false;
183469f35306SGunnar Mills 
183569f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
183669f35306SGunnar Mills     {
183769f35306SGunnar Mills         autoRebootEnabled = false;
183869f35306SGunnar Mills     }
183969f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
184069f35306SGunnar Mills     {
184169f35306SGunnar Mills         autoRebootEnabled = true;
184269f35306SGunnar Mills     }
184369f35306SGunnar Mills     else
184469f35306SGunnar Mills     {
18450fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
184669f35306SGunnar Mills                          << automaticRetryConfig;
184769f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
184869f35306SGunnar Mills                                          "AutomaticRetryConfig");
184969f35306SGunnar Mills         return;
185069f35306SGunnar Mills     }
185169f35306SGunnar Mills 
185269f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
18535e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
185469f35306SGunnar Mills         if (ec)
185569f35306SGunnar Mills         {
185669f35306SGunnar Mills             messages::internalError(aResp->res);
185769f35306SGunnar Mills             return;
185869f35306SGunnar Mills         }
185969f35306SGunnar Mills         },
186069f35306SGunnar Mills         "xyz.openbmc_project.Settings",
186169f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
186269f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
186369f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1864168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
186569f35306SGunnar Mills }
186669f35306SGunnar Mills 
186769f35306SGunnar Mills /**
1868c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1869c6a620f2SGeorge Liu  *
1870c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1871c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1872c6a620f2SGeorge Liu  *
1873c6a620f2SGeorge Liu  * @return None.
1874c6a620f2SGeorge Liu  */
18758d1b46d7Szhanghch05 inline void
18768d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18774e69c904SGunnar Mills                           const std::string& policy)
1878c6a620f2SGeorge Liu {
1879c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1880c6a620f2SGeorge Liu 
1881c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
18820fda0f12SGeorge Liu         {"AlwaysOn",
18830fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
18840fda0f12SGeorge Liu         {"AlwaysOff",
18850fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
18860fda0f12SGeorge Liu         {"LastState",
18870fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1888c6a620f2SGeorge Liu 
1889c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1890c6a620f2SGeorge Liu 
18914e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1892c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1893c6a620f2SGeorge Liu     {
18944e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
18954e69c904SGunnar Mills                                          "PowerRestorePolicy");
1896c6a620f2SGeorge Liu         return;
1897c6a620f2SGeorge Liu     }
1898c6a620f2SGeorge Liu 
1899c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1900c6a620f2SGeorge Liu 
1901c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
19025e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1903c6a620f2SGeorge Liu         if (ec)
1904c6a620f2SGeorge Liu         {
1905c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1906c6a620f2SGeorge Liu             return;
1907c6a620f2SGeorge Liu         }
1908c6a620f2SGeorge Liu         },
1909c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1910c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1911c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1912c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1913168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1914c6a620f2SGeorge Liu }
1915c6a620f2SGeorge Liu 
1916a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1917a6349918SAppaRao Puli /**
1918a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1919a6349918SAppaRao Puli  *
1920a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1921a6349918SAppaRao Puli  *
1922a6349918SAppaRao Puli  * @return None.
1923a6349918SAppaRao Puli  */
19248d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1925a6349918SAppaRao Puli {
1926a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1927bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1928bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1929bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
19305e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
1931b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1932b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1933b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
193450626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
193550626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
193650626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
193750626f4fSJames Feist 
1938a6349918SAppaRao Puli         if (ec)
1939a6349918SAppaRao Puli         {
1940a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1941b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1942b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1943a6349918SAppaRao Puli             return;
1944a6349918SAppaRao Puli         }
1945a6349918SAppaRao Puli 
1946a6349918SAppaRao Puli         const bool* provState = nullptr;
1947a6349918SAppaRao Puli         const bool* lockState = nullptr;
1948bc1d29deSKrzysztof Grobelny 
1949bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
19500d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
19510d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1952bc1d29deSKrzysztof Grobelny 
1953bc1d29deSKrzysztof Grobelny         if (!success)
1954a6349918SAppaRao Puli         {
1955bc1d29deSKrzysztof Grobelny             messages::internalError(aResp->res);
1956bc1d29deSKrzysztof Grobelny             return;
1957a6349918SAppaRao Puli         }
1958a6349918SAppaRao Puli 
1959a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1960a6349918SAppaRao Puli         {
1961a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1962a6349918SAppaRao Puli             messages::internalError(aResp->res);
1963a6349918SAppaRao Puli             return;
1964a6349918SAppaRao Puli         }
1965a6349918SAppaRao Puli 
1966a6349918SAppaRao Puli         if (*provState == true)
1967a6349918SAppaRao Puli         {
1968a6349918SAppaRao Puli             if (*lockState == true)
1969a6349918SAppaRao Puli             {
1970a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1971a6349918SAppaRao Puli             }
1972a6349918SAppaRao Puli             else
1973a6349918SAppaRao Puli             {
1974a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1975a6349918SAppaRao Puli             }
1976a6349918SAppaRao Puli         }
1977a6349918SAppaRao Puli         else
1978a6349918SAppaRao Puli         {
1979a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1980a6349918SAppaRao Puli         }
1981bc1d29deSKrzysztof Grobelny         });
1982a6349918SAppaRao Puli }
1983a6349918SAppaRao Puli #endif
1984a6349918SAppaRao Puli 
1985491d8ee7SSantosh Puranik /**
19863a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
19873a2d0424SChris Cain  *
19883a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19893a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
19903a2d0424SChris Cain  *
19913a2d0424SChris Cain  * @return None.
19923a2d0424SChris Cain  */
19933a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19943a2d0424SChris Cain                                const std::string& modeValue)
19953a2d0424SChris Cain {
19960fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
19973a2d0424SChris Cain     {
19983a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
19993a2d0424SChris Cain     }
20000fda0f12SGeorge Liu     else if (
20010fda0f12SGeorge Liu         modeValue ==
20020fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20033a2d0424SChris Cain     {
20043a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20053a2d0424SChris Cain     }
20060fda0f12SGeorge Liu     else if (modeValue ==
20070fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20083a2d0424SChris Cain     {
20093a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20103a2d0424SChris Cain     }
20110fda0f12SGeorge Liu     else if (modeValue ==
20120fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20133a2d0424SChris Cain     {
20143a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20153a2d0424SChris Cain     }
20163a2d0424SChris Cain     else
20173a2d0424SChris Cain     {
20183a2d0424SChris Cain         // Any other values would be invalid
20193a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20203a2d0424SChris Cain         messages::internalError(aResp->res);
20213a2d0424SChris Cain     }
20223a2d0424SChris Cain }
20233a2d0424SChris Cain 
20243a2d0424SChris Cain /**
20253a2d0424SChris Cain  * @brief Retrieves system power mode
20263a2d0424SChris Cain  *
20273a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20283a2d0424SChris Cain  *
20293a2d0424SChris Cain  * @return None.
20303a2d0424SChris Cain  */
20313a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
20323a2d0424SChris Cain {
20333a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
20343a2d0424SChris Cain 
20353a2d0424SChris Cain     // Get Power Mode object path:
2036e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2037e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2038e99073f5SGeorge Liu     dbus::utility::getSubTree(
2039e99073f5SGeorge Liu         "/", 0, interfaces,
2040e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2041b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
20423a2d0424SChris Cain         if (ec)
20433a2d0424SChris Cain         {
2044002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2045002d39b4SEd Tanous                              << ec;
20463a2d0424SChris Cain             // This is an optional D-Bus object so just return if
20473a2d0424SChris Cain             // error occurs
20483a2d0424SChris Cain             return;
20493a2d0424SChris Cain         }
20503a2d0424SChris Cain         if (subtree.empty())
20513a2d0424SChris Cain         {
20523a2d0424SChris Cain             // As noted above, this is an optional interface so just return
20533a2d0424SChris Cain             // if there is no instance found
20543a2d0424SChris Cain             return;
20553a2d0424SChris Cain         }
20563a2d0424SChris Cain         if (subtree.size() > 1)
20573a2d0424SChris Cain         {
20583a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
20593a2d0424SChris Cain             // error
20603a2d0424SChris Cain             BMCWEB_LOG_DEBUG
20613a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
20623a2d0424SChris Cain                 << subtree.size();
20633a2d0424SChris Cain             messages::internalError(aResp->res);
20643a2d0424SChris Cain             return;
20653a2d0424SChris Cain         }
20663a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
20673a2d0424SChris Cain         {
20683a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
20693a2d0424SChris Cain             messages::internalError(aResp->res);
20703a2d0424SChris Cain             return;
20713a2d0424SChris Cain         }
20723a2d0424SChris Cain         const std::string& path = subtree[0].first;
20733a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
20743a2d0424SChris Cain         if (service.empty())
20753a2d0424SChris Cain         {
20763a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20773a2d0424SChris Cain             messages::internalError(aResp->res);
20783a2d0424SChris Cain             return;
20793a2d0424SChris Cain         }
20803a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
20811e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
20821e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
20831e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
20845e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
20851e1e598dSJonathan Doman                     const std::string& pmode) {
20868a592810SEd Tanous             if (ec2)
20873a2d0424SChris Cain             {
2088002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
20898a592810SEd Tanous                                  << ec2;
20903a2d0424SChris Cain                 messages::internalError(aResp->res);
20913a2d0424SChris Cain                 return;
20923a2d0424SChris Cain             }
20933a2d0424SChris Cain 
2094002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2095002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
20963a2d0424SChris Cain 
20971e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
20981e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
20991e1e598dSJonathan Doman             });
2100e99073f5SGeorge Liu         });
21013a2d0424SChris Cain }
21023a2d0424SChris Cain 
21033a2d0424SChris Cain /**
21043a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21053a2d0424SChris Cain  * name associated with that string
21063a2d0424SChris Cain  *
21073a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21083a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21093a2d0424SChris Cain  *
21103a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21113a2d0424SChris Cain  */
21123a2d0424SChris Cain inline std::string
21133a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21143a2d0424SChris Cain                       const std::string& modeString)
21153a2d0424SChris Cain {
21163a2d0424SChris Cain     std::string mode;
21173a2d0424SChris Cain 
21183a2d0424SChris Cain     if (modeString == "Static")
21193a2d0424SChris Cain     {
21203a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21213a2d0424SChris Cain     }
21223a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21233a2d0424SChris Cain     {
21240fda0f12SGeorge Liu         mode =
21250fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21263a2d0424SChris Cain     }
21273a2d0424SChris Cain     else if (modeString == "PowerSaving")
21283a2d0424SChris Cain     {
21293a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21303a2d0424SChris Cain     }
21313a2d0424SChris Cain     else
21323a2d0424SChris Cain     {
21333a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
21343a2d0424SChris Cain     }
21353a2d0424SChris Cain     return mode;
21363a2d0424SChris Cain }
21373a2d0424SChris Cain 
21383a2d0424SChris Cain /**
21393a2d0424SChris Cain  * @brief Sets system power mode.
21403a2d0424SChris Cain  *
21413a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21423a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
21433a2d0424SChris Cain  *
21443a2d0424SChris Cain  * @return None.
21453a2d0424SChris Cain  */
21463a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21473a2d0424SChris Cain                          const std::string& pmode)
21483a2d0424SChris Cain {
21493a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
21503a2d0424SChris Cain 
21513a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
21523a2d0424SChris Cain     if (powerMode.empty())
21533a2d0424SChris Cain     {
21543a2d0424SChris Cain         return;
21553a2d0424SChris Cain     }
21563a2d0424SChris Cain 
21573a2d0424SChris Cain     // Get Power Mode object path:
2158e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2159e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2160e99073f5SGeorge Liu     dbus::utility::getSubTree(
2161e99073f5SGeorge Liu         "/", 0, interfaces,
2162b9d36b47SEd Tanous         [aResp,
2163e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2164b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21653a2d0424SChris Cain         if (ec)
21663a2d0424SChris Cain         {
2167002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2168002d39b4SEd Tanous                              << ec;
21693a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21703a2d0424SChris Cain             messages::internalError(aResp->res);
21713a2d0424SChris Cain             return;
21723a2d0424SChris Cain         }
21733a2d0424SChris Cain         if (subtree.empty())
21743a2d0424SChris Cain         {
21753a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21763a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
21773a2d0424SChris Cain                                        "PowerMode");
21783a2d0424SChris Cain             return;
21793a2d0424SChris Cain         }
21803a2d0424SChris Cain         if (subtree.size() > 1)
21813a2d0424SChris Cain         {
21823a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21833a2d0424SChris Cain             // error
21843a2d0424SChris Cain             BMCWEB_LOG_DEBUG
21853a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
21863a2d0424SChris Cain                 << subtree.size();
21873a2d0424SChris Cain             messages::internalError(aResp->res);
21883a2d0424SChris Cain             return;
21893a2d0424SChris Cain         }
21903a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21913a2d0424SChris Cain         {
21923a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21933a2d0424SChris Cain             messages::internalError(aResp->res);
21943a2d0424SChris Cain             return;
21953a2d0424SChris Cain         }
21963a2d0424SChris Cain         const std::string& path = subtree[0].first;
21973a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21983a2d0424SChris Cain         if (service.empty())
21993a2d0424SChris Cain         {
22003a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
22013a2d0424SChris Cain             messages::internalError(aResp->res);
22023a2d0424SChris Cain             return;
22033a2d0424SChris Cain         }
22043a2d0424SChris Cain 
22053a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22063a2d0424SChris Cain                          << path;
22073a2d0424SChris Cain 
22083a2d0424SChris Cain         // Set the Power Mode property
22093a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
22105e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
22118a592810SEd Tanous             if (ec2)
22123a2d0424SChris Cain             {
22133a2d0424SChris Cain                 messages::internalError(aResp->res);
22143a2d0424SChris Cain                 return;
22153a2d0424SChris Cain             }
22163a2d0424SChris Cain             },
22173a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
22183a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2219168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
2220e99073f5SGeorge Liu         });
22213a2d0424SChris Cain }
22223a2d0424SChris Cain 
22233a2d0424SChris Cain /**
222451709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
222551709ffdSYong Li  *
222651709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
222751709ffdSYong Li  *
222851709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
222951709ffdSYong Li  * translation cannot be done, returns an empty string.
223051709ffdSYong Li  */
223123a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
223251709ffdSYong Li {
223351709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
223451709ffdSYong Li     {
223551709ffdSYong Li         return "None";
223651709ffdSYong Li     }
22373174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
223851709ffdSYong Li     {
223951709ffdSYong Li         return "ResetSystem";
224051709ffdSYong Li     }
22413174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
224251709ffdSYong Li     {
224351709ffdSYong Li         return "PowerDown";
224451709ffdSYong Li     }
22453174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
224651709ffdSYong Li     {
224751709ffdSYong Li         return "PowerCycle";
224851709ffdSYong Li     }
224951709ffdSYong Li 
225051709ffdSYong Li     return "";
225151709ffdSYong Li }
225251709ffdSYong Li 
225351709ffdSYong Li /**
2254c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2255c45f0082SYong Li  *
2256c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2257c45f0082SYong Li  *
2258c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2259c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2260c45f0082SYong Li  */
2261c45f0082SYong Li 
226223a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2263c45f0082SYong Li {
2264c45f0082SYong Li     if (rfAction == "None")
2265c45f0082SYong Li     {
2266c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2267c45f0082SYong Li     }
22683174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2269c45f0082SYong Li     {
2270c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2271c45f0082SYong Li     }
22723174e4dfSEd Tanous     if (rfAction == "PowerDown")
2273c45f0082SYong Li     {
2274c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2275c45f0082SYong Li     }
22763174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2277c45f0082SYong Li     {
2278c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2279c45f0082SYong Li     }
2280c45f0082SYong Li 
2281c45f0082SYong Li     return "";
2282c45f0082SYong Li }
2283c45f0082SYong Li 
2284c45f0082SYong Li /**
228551709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
228651709ffdSYong Li  *
228751709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
228851709ffdSYong Li  *
228951709ffdSYong Li  * @return None.
229051709ffdSYong Li  */
22918d1b46d7Szhanghch05 inline void
22928d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
229351709ffdSYong Li {
229451709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2295bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2296bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2297bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2298bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
22995e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
2300b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
230151709ffdSYong Li         if (ec)
230251709ffdSYong Li         {
230351709ffdSYong Li             // watchdog service is stopped
230451709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
230551709ffdSYong Li             return;
230651709ffdSYong Li         }
230751709ffdSYong Li 
230851709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
230951709ffdSYong Li 
231051709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
231151709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
231251709ffdSYong Li 
231351709ffdSYong Li         // watchdog service is running/enabled
231451709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
231551709ffdSYong Li 
2316bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2317bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
231851709ffdSYong Li 
2319bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2320bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2321bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2322bc1d29deSKrzysztof Grobelny 
2323bc1d29deSKrzysztof Grobelny         if (!success)
232451709ffdSYong Li         {
232551709ffdSYong Li             messages::internalError(aResp->res);
2326601af5edSChicago Duan             return;
232751709ffdSYong Li         }
232851709ffdSYong Li 
2329bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
233051709ffdSYong Li         {
2331bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
233251709ffdSYong Li         }
233351709ffdSYong Li 
2334bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2335bc1d29deSKrzysztof Grobelny         {
2336bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
233751709ffdSYong Li             if (action.empty())
233851709ffdSYong Li             {
233951709ffdSYong Li                 messages::internalError(aResp->res);
2340601af5edSChicago Duan                 return;
234151709ffdSYong Li             }
234251709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
234351709ffdSYong Li         }
2344bc1d29deSKrzysztof Grobelny         });
234551709ffdSYong Li }
234651709ffdSYong Li 
234751709ffdSYong Li /**
2348c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2349c45f0082SYong Li  *
2350c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2351c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2352c45f0082SYong Li  *                       RF request.
2353c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2354c45f0082SYong Li  *
2355c45f0082SYong Li  * @return None.
2356c45f0082SYong Li  */
23578d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2358c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2359c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2360c45f0082SYong Li {
2361c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2362c45f0082SYong Li 
2363c45f0082SYong Li     if (wdtTimeOutAction)
2364c45f0082SYong Li     {
2365c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2366c45f0082SYong Li         // check if TimeOut Action is Valid
2367c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2368c45f0082SYong Li         {
2369c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2370c45f0082SYong Li                              << *wdtTimeOutAction;
2371c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2372c45f0082SYong Li                                              "TimeoutAction");
2373c45f0082SYong Li             return;
2374c45f0082SYong Li         }
2375c45f0082SYong Li 
2376c45f0082SYong Li         crow::connections::systemBus->async_method_call(
23775e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2378c45f0082SYong Li             if (ec)
2379c45f0082SYong Li             {
2380c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2381c45f0082SYong Li                 messages::internalError(aResp->res);
2382c45f0082SYong Li                 return;
2383c45f0082SYong Li             }
2384c45f0082SYong Li             },
2385c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2386c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2387c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2388c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2389168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2390c45f0082SYong Li     }
2391c45f0082SYong Li 
2392c45f0082SYong Li     if (wdtEnable)
2393c45f0082SYong Li     {
2394c45f0082SYong Li         crow::connections::systemBus->async_method_call(
23955e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2396c45f0082SYong Li             if (ec)
2397c45f0082SYong Li             {
2398c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2399c45f0082SYong Li                 messages::internalError(aResp->res);
2400c45f0082SYong Li                 return;
2401c45f0082SYong Li             }
2402c45f0082SYong Li             },
2403c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2404c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2405c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2406c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2407168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2408c45f0082SYong Li     }
2409c45f0082SYong Li }
2410c45f0082SYong Li 
241137bbf98cSChris Cain /**
241237bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
241337bbf98cSChris Cain  *
241437bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
241537bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
241637bbf98cSChris Cain  *
241737bbf98cSChris Cain  * @return true if successful
241837bbf98cSChris Cain  */
24191e5b7c88SJiaqing Zhao inline bool
24201e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
24211e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
242237bbf98cSChris Cain {
2423bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2424bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2425bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2426bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2427bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2428bc1d29deSKrzysztof Grobelny 
2429bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2430bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
24312661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
24322661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
24332661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2434bc1d29deSKrzysztof Grobelny 
2435bc1d29deSKrzysztof Grobelny     if (!success)
243637bbf98cSChris Cain     {
243737bbf98cSChris Cain         return false;
243837bbf98cSChris Cain     }
2439bc1d29deSKrzysztof Grobelny 
2440bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
244137bbf98cSChris Cain     {
2442bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
244337bbf98cSChris Cain     }
2444bc1d29deSKrzysztof Grobelny 
2445bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
244637bbf98cSChris Cain     {
2447bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2448bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
244937bbf98cSChris Cain     }
2450bc1d29deSKrzysztof Grobelny 
2451bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2452bc1d29deSKrzysztof Grobelny     {
2453bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
245437bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
245537bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
245637bbf98cSChris Cain                 .count();
245737bbf98cSChris Cain     }
2458bc1d29deSKrzysztof Grobelny 
2459bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
246037bbf98cSChris Cain     {
2461bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2462bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
246337bbf98cSChris Cain     }
2464bc1d29deSKrzysztof Grobelny 
2465bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
246637bbf98cSChris Cain     {
2467bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
246837bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
246937bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
247037bbf98cSChris Cain                 .count();
247137bbf98cSChris Cain     }
247237bbf98cSChris Cain 
247337bbf98cSChris Cain     return true;
247437bbf98cSChris Cain }
247537bbf98cSChris Cain 
247637bbf98cSChris Cain /**
247737bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
247837bbf98cSChris Cain  *
247937bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
248037bbf98cSChris Cain  *
248137bbf98cSChris Cain  * @return None.
248237bbf98cSChris Cain  */
248337bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
248437bbf98cSChris Cain {
248537bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
248637bbf98cSChris Cain 
248737bbf98cSChris Cain     // Get IdlePowerSaver object path:
2488e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2489e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2490e99073f5SGeorge Liu     dbus::utility::getSubTree(
2491e99073f5SGeorge Liu         "/", 0, interfaces,
2492e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2493b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
249437bbf98cSChris Cain         if (ec)
249537bbf98cSChris Cain         {
249637bbf98cSChris Cain             BMCWEB_LOG_DEBUG
249737bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
249837bbf98cSChris Cain                 << ec;
249937bbf98cSChris Cain             messages::internalError(aResp->res);
250037bbf98cSChris Cain             return;
250137bbf98cSChris Cain         }
250237bbf98cSChris Cain         if (subtree.empty())
250337bbf98cSChris Cain         {
250437bbf98cSChris Cain             // This is an optional interface so just return
250537bbf98cSChris Cain             // if there is no instance found
250637bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
250737bbf98cSChris Cain             return;
250837bbf98cSChris Cain         }
250937bbf98cSChris Cain         if (subtree.size() > 1)
251037bbf98cSChris Cain         {
251137bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
251237bbf98cSChris Cain             // is an error
251337bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
251437bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
251537bbf98cSChris Cain                              << subtree.size();
251637bbf98cSChris Cain             messages::internalError(aResp->res);
251737bbf98cSChris Cain             return;
251837bbf98cSChris Cain         }
251937bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
252037bbf98cSChris Cain         {
252137bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
252237bbf98cSChris Cain             messages::internalError(aResp->res);
252337bbf98cSChris Cain             return;
252437bbf98cSChris Cain         }
252537bbf98cSChris Cain         const std::string& path = subtree[0].first;
252637bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
252737bbf98cSChris Cain         if (service.empty())
252837bbf98cSChris Cain         {
2529002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
253037bbf98cSChris Cain             messages::internalError(aResp->res);
253137bbf98cSChris Cain             return;
253237bbf98cSChris Cain         }
253337bbf98cSChris Cain 
253437bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2535bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2536bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2537bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
25385e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
25391e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
25408a592810SEd Tanous             if (ec2)
254137bbf98cSChris Cain             {
254237bbf98cSChris Cain                 BMCWEB_LOG_ERROR
25438a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
254437bbf98cSChris Cain                 messages::internalError(aResp->res);
254537bbf98cSChris Cain                 return;
254637bbf98cSChris Cain             }
254737bbf98cSChris Cain 
2548e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
254937bbf98cSChris Cain             {
255037bbf98cSChris Cain                 messages::internalError(aResp->res);
255137bbf98cSChris Cain                 return;
255237bbf98cSChris Cain             }
2553bc1d29deSKrzysztof Grobelny             });
2554e99073f5SGeorge Liu         });
255537bbf98cSChris Cain 
255637bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
255737bbf98cSChris Cain }
255837bbf98cSChris Cain 
255937bbf98cSChris Cain /**
256037bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
256137bbf98cSChris Cain  *
256237bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
256337bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
256437bbf98cSChris Cain  *                       RF request.
256537bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
256637bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
256737bbf98cSChris Cain  * before entering idle state.
256837bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
256937bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
257037bbf98cSChris Cain  * before exiting idle state
257137bbf98cSChris Cain  *
257237bbf98cSChris Cain  * @return None.
257337bbf98cSChris Cain  */
257437bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
257537bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
257637bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
257737bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
257837bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
257937bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
258037bbf98cSChris Cain {
258137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
258237bbf98cSChris Cain 
258337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2584e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2585e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2586e99073f5SGeorge Liu     dbus::utility::getSubTree(
2587e99073f5SGeorge Liu         "/", 0, interfaces,
258837bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2589e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2590b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
259137bbf98cSChris Cain         if (ec)
259237bbf98cSChris Cain         {
259337bbf98cSChris Cain             BMCWEB_LOG_DEBUG
259437bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
259537bbf98cSChris Cain                 << ec;
259637bbf98cSChris Cain             messages::internalError(aResp->res);
259737bbf98cSChris Cain             return;
259837bbf98cSChris Cain         }
259937bbf98cSChris Cain         if (subtree.empty())
260037bbf98cSChris Cain         {
260137bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
260237bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
260337bbf98cSChris Cain                                        "IdlePowerSaver");
260437bbf98cSChris Cain             return;
260537bbf98cSChris Cain         }
260637bbf98cSChris Cain         if (subtree.size() > 1)
260737bbf98cSChris Cain         {
260837bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
260937bbf98cSChris Cain             // is an error
26100fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
26110fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
261237bbf98cSChris Cain                 << subtree.size();
261337bbf98cSChris Cain             messages::internalError(aResp->res);
261437bbf98cSChris Cain             return;
261537bbf98cSChris Cain         }
261637bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
261737bbf98cSChris Cain         {
261837bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
261937bbf98cSChris Cain             messages::internalError(aResp->res);
262037bbf98cSChris Cain             return;
262137bbf98cSChris Cain         }
262237bbf98cSChris Cain         const std::string& path = subtree[0].first;
262337bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
262437bbf98cSChris Cain         if (service.empty())
262537bbf98cSChris Cain         {
2626002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
262737bbf98cSChris Cain             messages::internalError(aResp->res);
262837bbf98cSChris Cain             return;
262937bbf98cSChris Cain         }
263037bbf98cSChris Cain 
263137bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
263237bbf98cSChris Cain         // need to be updated
263337bbf98cSChris Cain 
263437bbf98cSChris Cain         if (ipsEnable)
263537bbf98cSChris Cain         {
263637bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26375e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26388a592810SEd Tanous                 if (ec2)
263937bbf98cSChris Cain                 {
26408a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
264137bbf98cSChris Cain                     messages::internalError(aResp->res);
264237bbf98cSChris Cain                     return;
264337bbf98cSChris Cain                 }
264437bbf98cSChris Cain                 },
264537bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2646002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2647002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
264837bbf98cSChris Cain         }
264937bbf98cSChris Cain         if (ipsEnterUtil)
265037bbf98cSChris Cain         {
265137bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26525e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26538a592810SEd Tanous                 if (ec2)
265437bbf98cSChris Cain                 {
26558a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
265637bbf98cSChris Cain                     messages::internalError(aResp->res);
265737bbf98cSChris Cain                     return;
265837bbf98cSChris Cain                 }
265937bbf98cSChris Cain                 },
266037bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
266137bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
266237bbf98cSChris Cain                 "EnterUtilizationPercent",
2663168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
266437bbf98cSChris Cain         }
266537bbf98cSChris Cain         if (ipsEnterTime)
266637bbf98cSChris Cain         {
266737bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
266837bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
266937bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26705e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26718a592810SEd Tanous                 if (ec2)
267237bbf98cSChris Cain                 {
26738a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
267437bbf98cSChris Cain                     messages::internalError(aResp->res);
267537bbf98cSChris Cain                     return;
267637bbf98cSChris Cain                 }
267737bbf98cSChris Cain                 },
267837bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
267937bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2680168e20c1SEd Tanous                 "EnterDwellTime",
2681168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
268237bbf98cSChris Cain         }
268337bbf98cSChris Cain         if (ipsExitUtil)
268437bbf98cSChris Cain         {
268537bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26865e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26878a592810SEd Tanous                 if (ec2)
268837bbf98cSChris Cain                 {
26898a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
269037bbf98cSChris Cain                     messages::internalError(aResp->res);
269137bbf98cSChris Cain                     return;
269237bbf98cSChris Cain                 }
269337bbf98cSChris Cain                 },
269437bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
269537bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
269637bbf98cSChris Cain                 "ExitUtilizationPercent",
2697168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
269837bbf98cSChris Cain         }
269937bbf98cSChris Cain         if (ipsExitTime)
270037bbf98cSChris Cain         {
270137bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
270237bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
270337bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
27045e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
27058a592810SEd Tanous                 if (ec2)
270637bbf98cSChris Cain                 {
27078a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
270837bbf98cSChris Cain                     messages::internalError(aResp->res);
270937bbf98cSChris Cain                     return;
271037bbf98cSChris Cain                 }
271137bbf98cSChris Cain                 },
271237bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
271337bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2714168e20c1SEd Tanous                 "ExitDwellTime",
2715168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
271637bbf98cSChris Cain         }
2717e99073f5SGeorge Liu         });
271837bbf98cSChris Cain 
271937bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
272037bbf98cSChris Cain }
272137bbf98cSChris Cain 
2722dd60b9edSEd Tanous inline void handleComputerSystemHead(
2723dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2724dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2725dd60b9edSEd Tanous {
2726dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2727dd60b9edSEd Tanous     {
2728dd60b9edSEd Tanous         return;
2729dd60b9edSEd Tanous     }
2730dd60b9edSEd Tanous     asyncResp->res.addHeader(
2731dd60b9edSEd Tanous         boost::beast::http::field::link,
2732dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2733dd60b9edSEd Tanous }
2734dd60b9edSEd Tanous 
2735c45f0082SYong Li /**
2736c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2737c5b2abe0SLewanczyk, Dawid  * Schema
2738c5b2abe0SLewanczyk, Dawid  */
27397e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
27401abe55efSEd Tanous {
27417e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2742dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2743dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2744dd60b9edSEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
2745dd60b9edSEd Tanous 
2746dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2747ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
27487e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2749f4c99e70SEd Tanous             [&app](const crow::Request& req,
27507e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27513ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2752f4c99e70SEd Tanous         {
2753f4c99e70SEd Tanous             return;
2754f4c99e70SEd Tanous         }
2755dd60b9edSEd Tanous 
2756dd60b9edSEd Tanous         asyncResp->res.addHeader(
2757dd60b9edSEd Tanous             boost::beast::http::field::link,
2758dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
27598d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
27600f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
27618d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
27628d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2763462023adSSunitha Harish 
27641e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2765002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
27661e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2767002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
27685e7e2dc5SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27691e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2770002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
27712c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2772002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
27731476687dSEd Tanous 
27741476687dSEd Tanous             nlohmann::json::object_t system;
27751476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
27761476687dSEd Tanous             ifaceArray.push_back(std::move(system));
277794bda602STim Lee             count = ifaceArray.size();
27788a592810SEd Tanous             if (!ec2)
2779462023adSSunitha Harish             {
2780462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
27811476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2782002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
27831476687dSEd Tanous                 ifaceArray.push_back(std::move(hypervisor));
27842c70f800SEd Tanous                 count = ifaceArray.size();
2785cb13a392SEd Tanous             }
27861e1e598dSJonathan Doman             });
27877e860f15SJohn Edward Broadbent         });
2788c5b2abe0SLewanczyk, Dawid }
27897e860f15SJohn Edward Broadbent 
27907e860f15SJohn Edward Broadbent /**
27917e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
27927e860f15SJohn Edward Broadbent  */
27934f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27947e860f15SJohn Edward Broadbent {
27957e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
27967e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
27977e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
27987e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
27997e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
28007e860f15SJohn Edward Broadbent 
28017e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28025e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28037e860f15SJohn Edward Broadbent         if (ec)
28047e860f15SJohn Edward Broadbent         {
28057e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
28067e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
28077e860f15SJohn Edward Broadbent             return;
28087e860f15SJohn Edward Broadbent         }
28097e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
28107e860f15SJohn Edward Broadbent         },
28117e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28127e860f15SJohn Edward Broadbent }
2813c5b2abe0SLewanczyk, Dawid 
2814c5b2abe0SLewanczyk, Dawid /**
2815cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2816cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2817cc340dd9SEd Tanous  */
28187e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2819cc340dd9SEd Tanous {
2820cc340dd9SEd Tanous     /**
2821cc340dd9SEd Tanous      * Function handles POST method request.
2822cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2823cc340dd9SEd Tanous      */
28247e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
28257e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2826ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2827002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2828002d39b4SEd Tanous             [&app](const crow::Request& req,
28297e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28303ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
283145ca1b86SEd Tanous         {
283245ca1b86SEd Tanous             return;
283345ca1b86SEd Tanous         }
28349712f8acSEd Tanous         std::string resetType;
283515ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
28367e860f15SJohn Edward Broadbent                                        resetType))
2837cc340dd9SEd Tanous         {
2838cc340dd9SEd Tanous             return;
2839cc340dd9SEd Tanous         }
2840cc340dd9SEd Tanous 
2841d22c8396SJason M. Bills         // Get the command and host vs. chassis
2842cc340dd9SEd Tanous         std::string command;
2843543f4400SEd Tanous         bool hostCommand = true;
2844d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2845cc340dd9SEd Tanous         {
2846cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2847d22c8396SJason M. Bills             hostCommand = true;
2848d22c8396SJason M. Bills         }
2849d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2850d22c8396SJason M. Bills         {
2851d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2852d22c8396SJason M. Bills             hostCommand = false;
2853d22c8396SJason M. Bills         }
2854d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2855d22c8396SJason M. Bills         {
285686a0851aSJason M. Bills             command =
285786a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
285886a0851aSJason M. Bills             hostCommand = true;
2859cc340dd9SEd Tanous         }
28609712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2861cc340dd9SEd Tanous         {
2862cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2863d22c8396SJason M. Bills             hostCommand = true;
2864cc340dd9SEd Tanous         }
28659712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2866cc340dd9SEd Tanous         {
28670fda0f12SGeorge Liu             command =
28680fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2869d22c8396SJason M. Bills             hostCommand = true;
2870d22c8396SJason M. Bills         }
2871d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2872d22c8396SJason M. Bills         {
287386a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
287486a0851aSJason M. Bills             hostCommand = true;
2875cc340dd9SEd Tanous         }
2876bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2877bfd5b826SLakshminarayana R. Kammath         {
2878bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2879bfd5b826SLakshminarayana R. Kammath             return;
2880bfd5b826SLakshminarayana R. Kammath         }
2881cc340dd9SEd Tanous         else
2882cc340dd9SEd Tanous         {
28838d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
28848d1b46d7Szhanghch05                                              resetType);
2885cc340dd9SEd Tanous             return;
2886cc340dd9SEd Tanous         }
2887cc340dd9SEd Tanous 
2888d22c8396SJason M. Bills         if (hostCommand)
2889d22c8396SJason M. Bills         {
2890cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
28915e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2892cc340dd9SEd Tanous                 if (ec)
2893cc340dd9SEd Tanous                 {
2894cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2895002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2896d22c8396SJason M. Bills                     {
2897d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2898d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2899d22c8396SJason M. Bills                     }
2900d22c8396SJason M. Bills                     else
2901d22c8396SJason M. Bills                     {
2902f12894f8SJason M. Bills                         messages::internalError(asyncResp->res);
2903d22c8396SJason M. Bills                     }
2904cc340dd9SEd Tanous                     return;
2905cc340dd9SEd Tanous                 }
2906f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2907cc340dd9SEd Tanous                 },
2908cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2909cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2910cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
29119712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2912168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2913cc340dd9SEd Tanous         }
2914d22c8396SJason M. Bills         else
2915d22c8396SJason M. Bills         {
2916d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
29175e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2918d22c8396SJason M. Bills                 if (ec)
2919d22c8396SJason M. Bills                 {
2920d22c8396SJason M. Bills                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2921002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2922d22c8396SJason M. Bills                     {
2923d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2924d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2925d22c8396SJason M. Bills                     }
2926d22c8396SJason M. Bills                     else
2927d22c8396SJason M. Bills                     {
2928d22c8396SJason M. Bills                         messages::internalError(asyncResp->res);
2929d22c8396SJason M. Bills                     }
2930d22c8396SJason M. Bills                     return;
2931d22c8396SJason M. Bills                 }
2932d22c8396SJason M. Bills                 messages::success(asyncResp->res);
2933d22c8396SJason M. Bills                 },
2934d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
2935d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
2936d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
2937002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2938168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2939d22c8396SJason M. Bills         }
29407e860f15SJohn Edward Broadbent         });
2941d22c8396SJason M. Bills }
2942cc340dd9SEd Tanous 
294338c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead(
2944dd60b9edSEd Tanous     App& app, const crow::Request& req,
2945dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2946dd60b9edSEd Tanous {
2947dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2948dd60b9edSEd Tanous     {
2949dd60b9edSEd Tanous         return;
2950dd60b9edSEd Tanous     }
2951dd60b9edSEd Tanous 
2952dd60b9edSEd Tanous     asyncResp->res.addHeader(
2953dd60b9edSEd Tanous         boost::beast::http::field::link,
2954dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2955dd60b9edSEd Tanous }
2956dd60b9edSEd Tanous 
29575c3e9272SAbhishek Patel inline void afterPortRequest(
29585c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29595c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29605c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29615c3e9272SAbhishek Patel {
29625c3e9272SAbhishek Patel     if (ec)
29635c3e9272SAbhishek Patel     {
29645c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29655c3e9272SAbhishek Patel         return;
29665c3e9272SAbhishek Patel     }
29675c3e9272SAbhishek Patel     for (const auto& data : socketData)
29685c3e9272SAbhishek Patel     {
29695c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29705c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29715c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29725c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29735c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29745c3e9272SAbhishek Patel         // need to retrieve port number for
29755c3e9272SAbhishek Patel         // obmc-console-ssh service
29765c3e9272SAbhishek Patel         if (protocolName == "SSH")
29775c3e9272SAbhishek Patel         {
29785c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
29795c3e9272SAbhishek Patel                                           const boost::system::error_code ec1,
29805c3e9272SAbhishek Patel                                           int portNumber) {
29815c3e9272SAbhishek Patel                 if (ec1)
29825c3e9272SAbhishek Patel                 {
29835c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
29845c3e9272SAbhishek Patel                     return;
29855c3e9272SAbhishek Patel                 }
29865c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
29875c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
29885c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
29895c3e9272SAbhishek Patel             });
29905c3e9272SAbhishek Patel         }
29915c3e9272SAbhishek Patel     }
29925c3e9272SAbhishek Patel }
2993cc340dd9SEd Tanous /**
29946617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2995c5b2abe0SLewanczyk, Dawid  */
29967e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
29971abe55efSEd Tanous {
2998c5b2abe0SLewanczyk, Dawid 
2999dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3000dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3001dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
3002dd60b9edSEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3003c5b2abe0SLewanczyk, Dawid     /**
3004c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
3005c5b2abe0SLewanczyk, Dawid      */
300622d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3007ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3008002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
3009002d39b4SEd Tanous             [&app](const crow::Request& req,
301022d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
301122d268cbSEd Tanous                    const std::string& systemName) {
30123ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
301345ca1b86SEd Tanous         {
301445ca1b86SEd Tanous             return;
301545ca1b86SEd Tanous         }
3016746b56f3SAsmitha Karunanithi 
3017746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3018746b56f3SAsmitha Karunanithi         {
3019746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
3020746b56f3SAsmitha Karunanithi             return;
3021746b56f3SAsmitha Karunanithi         }
3022746b56f3SAsmitha Karunanithi 
302322d268cbSEd Tanous         if (systemName != "system")
302422d268cbSEd Tanous         {
302522d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
302622d268cbSEd Tanous                                        systemName);
302722d268cbSEd Tanous             return;
302822d268cbSEd Tanous         }
3029dd60b9edSEd Tanous         asyncResp->res.addHeader(
3030dd60b9edSEd Tanous             boost::beast::http::field::link,
3031dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30328d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
303337bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
30348d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
30358d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
30368d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
30378d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
30388d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
30398d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
30408d1b46d7Szhanghch05             "Disabled";
30418d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
30428d1b46d7Szhanghch05             uint64_t(0);
30438d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
30448d1b46d7Szhanghch05             "Disabled";
3045002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
304604a258f4SEd Tanous 
30471476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
30481476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
30491476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
30501476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
30511476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
30521476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
30533179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
30543179105bSSunny Srivastava             "/redfish/v1/Systems/system/FabricAdapters";
3055029573d4SEd Tanous 
3056002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
30571476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
30581476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
30591476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
30601476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
3061c5b2abe0SLewanczyk, Dawid 
30621476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
30631476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
30641476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
30651476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
3066c4bf6374SJason M. Bills 
30671476687dSEd Tanous         nlohmann::json::array_t managedBy;
30681476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
30691476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3070002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
30711476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
30721476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
30730e8ac5e7SGunnar Mills 
30740e8ac5e7SGunnar Mills         // Fill in SerialConsole info
3075002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3076002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3077002d39b4SEd Tanous             true;
30781476687dSEd Tanous 
30790e8ac5e7SGunnar Mills         // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
30801476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
30811476687dSEd Tanous             true;
30821476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
30831476687dSEd Tanous         asyncResp->res
30841476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
30851476687dSEd Tanous             "Press ~. to exit console";
30865c3e9272SAbhishek Patel         getPortStatusAndPath(std::span{protocolToDBusForSystems},
30875c3e9272SAbhishek Patel                              std::bind_front(afterPortRequest, asyncResp));
30880e8ac5e7SGunnar Mills 
30890e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
30900e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3091002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3092002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3093002d39b4SEd Tanous             4;
3094613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3095613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
30961476687dSEd Tanous 
30970e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
30987a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3099b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
31002ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3101e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3102e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3103b49ac873SJames Feist 
3104b49ac873SJames Feist         auto health = std::make_shared<HealthPopulate>(asyncResp);
31057a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
31067a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
31077a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3108914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3109b49ac873SJames Feist             if (ec)
3110b49ac873SJames Feist             {
3111b49ac873SJames Feist                 // no inventory
3112b49ac873SJames Feist                 return;
3113b49ac873SJames Feist             }
3114b49ac873SJames Feist 
3115914e2d5dSEd Tanous             health->inventory = resp;
31167a1dbc48SGeorge Liu             });
3117b49ac873SJames Feist 
3118b49ac873SJames Feist         health->populate();
3119b49ac873SJames Feist 
3120002d39b4SEd Tanous         getMainChassisId(asyncResp,
3121002d39b4SEd Tanous                          [](const std::string& chassisId,
31228d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3123b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3124b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3125eddfc437SWilly Tu             chassis["@odata.id"] = crow::utility::urlFromPieces(
3126eddfc437SWilly Tu                 "redfish", "v1", "Chassis", chassisId);
3127002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3128c5d03ff4SJennifer Lee         });
3129a3002228SAppaRao Puli 
31309f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
31319f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3132a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
31335bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
31346c34de48SEd Tanous         getHostState(asyncResp);
3135491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
3136978b8803SAndrew Geissler         getBootProgress(asyncResp);
3137b6d5d45cSHieu Huynh         getBootProgressLastStateTime(asyncResp);
3138adbe192aSJason M. Bills         getPCIeDeviceList(asyncResp, "PCIeDevices");
313951709ffdSYong Li         getHostWatchdogTimer(asyncResp);
3140c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
3141*797d5daeSCorey Hardesty         getAutomaticRetryPolicy(asyncResp);
3142c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
3143a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3144a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
3145a6349918SAppaRao Puli #endif
31461981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
31473a2d0424SChris Cain         getPowerMode(asyncResp);
314837bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
31497e860f15SJohn Edward Broadbent         });
3150550a6bf8SJiaqing Zhao 
315122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3152ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
31537e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
315445ca1b86SEd Tanous             [&app](const crow::Request& req,
315522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
315622d268cbSEd Tanous                    const std::string& systemName) {
31573ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
315845ca1b86SEd Tanous         {
315945ca1b86SEd Tanous             return;
316045ca1b86SEd Tanous         }
316122d268cbSEd Tanous         if (systemName != "system")
316222d268cbSEd Tanous         {
316322d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
316422d268cbSEd Tanous                                        systemName);
316522d268cbSEd Tanous             return;
316622d268cbSEd Tanous         }
316722d268cbSEd Tanous 
3168dd60b9edSEd Tanous         asyncResp->res.addHeader(
3169dd60b9edSEd Tanous             boost::beast::http::field::link,
3170dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3171dd60b9edSEd Tanous 
31729f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
3173cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
317498e386ecSGunnar Mills         std::optional<std::string> assetTag;
3175c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
31763a2d0424SChris Cain         std::optional<std::string> powerMode;
3177550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
3178550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
3179550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
3180550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
3181550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
3182550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
3183*797d5daeSCorey Hardesty         std::optional<uint32_t> bootAutomaticRetryAttempts;
3184550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
3185550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
3186550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
3187550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
3188550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
3189550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
3190550a6bf8SJiaqing Zhao 
3191550a6bf8SJiaqing Zhao         // clang-format off
319215ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3193550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3194550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
31957e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3196550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3197550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3198550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3199550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3200550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3201550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3202550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3203550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3204550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3205*797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3206550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3207550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3208550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3209550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3210550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3211550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
32126617338dSEd Tanous                 {
32136617338dSEd Tanous                     return;
32146617338dSEd Tanous                 }
3215550a6bf8SJiaqing Zhao         // clang-format on
3216491d8ee7SSantosh Puranik 
32178d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3218c45f0082SYong Li 
321998e386ecSGunnar Mills         if (assetTag)
322098e386ecSGunnar Mills         {
322198e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
322298e386ecSGunnar Mills         }
322398e386ecSGunnar Mills 
3224550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3225c45f0082SYong Li         {
3226f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3227c45f0082SYong Li         }
3228c45f0082SYong Li 
3229cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
323069f35306SGunnar Mills         {
3231002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3232491d8ee7SSantosh Puranik         }
3233550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
323469f35306SGunnar Mills         {
3235550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
323669f35306SGunnar Mills         }
3237ac7e1e0bSAli Ahmed 
3238*797d5daeSCorey Hardesty         if (bootAutomaticRetryAttempts)
3239*797d5daeSCorey Hardesty         {
3240*797d5daeSCorey Hardesty             setAutomaticRetryAttempts(asyncResp,
3241*797d5daeSCorey Hardesty                                       bootAutomaticRetryAttempts.value());
3242*797d5daeSCorey Hardesty         }
3243*797d5daeSCorey Hardesty 
3244550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3245ac7e1e0bSAli Ahmed         {
3246550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3247550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
324869f35306SGunnar Mills         }
3249265c1602SJohnathan Mantey 
32509f8bfa7cSGunnar Mills         if (locationIndicatorActive)
32519f8bfa7cSGunnar Mills         {
3252002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32539f8bfa7cSGunnar Mills         }
32549f8bfa7cSGunnar Mills 
32557e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
32567e860f15SJohn Edward Broadbent         // passed
32579712f8acSEd Tanous         if (indicatorLed)
32586617338dSEd Tanous         {
3259f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3260002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3261d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3262d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
32636617338dSEd Tanous         }
3264c6a620f2SGeorge Liu 
3265c6a620f2SGeorge Liu         if (powerRestorePolicy)
3266c6a620f2SGeorge Liu         {
32674e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3268c6a620f2SGeorge Liu         }
32693a2d0424SChris Cain 
32703a2d0424SChris Cain         if (powerMode)
32713a2d0424SChris Cain         {
32723a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
32733a2d0424SChris Cain         }
327437bbf98cSChris Cain 
3275550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3276550a6bf8SJiaqing Zhao             ipsExitTime)
327737bbf98cSChris Cain         {
3278002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3279002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
328037bbf98cSChris Cain         }
32817e860f15SJohn Edward Broadbent         });
3282c5b2abe0SLewanczyk, Dawid }
32831cb1a9e6SAppaRao Puli 
328438c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3285dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
3286dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3287dd60b9edSEd Tanous {
3288dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3289dd60b9edSEd Tanous     {
3290dd60b9edSEd Tanous         return;
3291dd60b9edSEd Tanous     }
3292dd60b9edSEd Tanous     asyncResp->res.addHeader(
3293dd60b9edSEd Tanous         boost::beast::http::field::link,
3294dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3295dd60b9edSEd Tanous }
3296dd60b9edSEd Tanous 
32971cb1a9e6SAppaRao Puli /**
32981cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
32991cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
33001cb1a9e6SAppaRao Puli  */
33017e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
33021cb1a9e6SAppaRao Puli {
3303dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3304dd60b9edSEd Tanous         .privileges(redfish::privileges::headActionInfo)
3305dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3306dd60b9edSEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
33071cb1a9e6SAppaRao Puli     /**
33081cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
33091cb1a9e6SAppaRao Puli      */
331022d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3311ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
33127e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
331345ca1b86SEd Tanous             [&app](const crow::Request& req,
331422d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331522d268cbSEd Tanous                    const std::string& systemName) {
33163ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
331745ca1b86SEd Tanous         {
331845ca1b86SEd Tanous             return;
331945ca1b86SEd Tanous         }
3320746b56f3SAsmitha Karunanithi 
3321746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3322746b56f3SAsmitha Karunanithi         {
3323746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3324746b56f3SAsmitha Karunanithi             return;
3325746b56f3SAsmitha Karunanithi         }
3326746b56f3SAsmitha Karunanithi 
332722d268cbSEd Tanous         if (systemName != "system")
332822d268cbSEd Tanous         {
332922d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
333022d268cbSEd Tanous                                        systemName);
333122d268cbSEd Tanous             return;
333222d268cbSEd Tanous         }
333322d268cbSEd Tanous 
3334dd60b9edSEd Tanous         asyncResp->res.addHeader(
3335dd60b9edSEd Tanous             boost::beast::http::field::link,
3336dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
33371476687dSEd Tanous 
33381476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
33391476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
33401476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
33411476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
33421476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
33431476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
33443215e700SNan Zhou 
33453215e700SNan Zhou         nlohmann::json::array_t parameters;
33463215e700SNan Zhou         nlohmann::json::object_t parameter;
33473215e700SNan Zhou 
33483215e700SNan Zhou         parameter["Name"] = "ResetType";
33493215e700SNan Zhou         parameter["Required"] = true;
33503215e700SNan Zhou         parameter["DataType"] = "String";
33513215e700SNan Zhou         nlohmann::json::array_t allowableValues;
33523215e700SNan Zhou         allowableValues.emplace_back("On");
33533215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
33543215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
33553215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
33563215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
33573215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
33583215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
33593215e700SNan Zhou         allowableValues.emplace_back("Nmi");
33603215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
33613215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
33623215e700SNan Zhou 
33633215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
33647e860f15SJohn Edward Broadbent         });
33651cb1a9e6SAppaRao Puli }
3366c5b2abe0SLewanczyk, Dawid } // namespace redfish
3367