xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision ef4c65b741724d724452a3a0efe8dff0d450514a)
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>
35*ef4c65b7SEd Tanous #include <boost/url/format.hpp>
361e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
37bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
381214b7e7SGunnar Mills 
397a1dbc48SGeorge Liu #include <array>
407a1dbc48SGeorge Liu #include <string_view>
41abf2add6SEd Tanous #include <variant>
42c5b2abe0SLewanczyk, Dawid 
431abe55efSEd Tanous namespace redfish
441abe55efSEd Tanous {
45c5b2abe0SLewanczyk, Dawid 
465c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
475c3e9272SAbhishek Patel     protocolToDBusForSystems{
485c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
495c3e9272SAbhishek Patel 
509d3ae10eSAlpana Kumari /**
519d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
529d3ae10eSAlpana Kumari  *
539d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
549d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
559d3ae10eSAlpana Kumari  *
569d3ae10eSAlpana Kumari  * @return None.
579d3ae10eSAlpana Kumari  */
588d1b46d7Szhanghch05 inline void
598d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
601e1e598dSJonathan Doman                          bool isDimmFunctional)
619d3ae10eSAlpana Kumari {
621e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
639d3ae10eSAlpana Kumari 
649d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
659d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
669d3ae10eSAlpana Kumari     // ENABLED.
6702cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
689d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
699d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
709d3ae10eSAlpana Kumari     {
71e05aec50SEd Tanous         if (isDimmFunctional)
729d3ae10eSAlpana Kumari         {
739d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
749d3ae10eSAlpana Kumari                 "Enabled";
759d3ae10eSAlpana Kumari         }
769d3ae10eSAlpana Kumari     }
779d3ae10eSAlpana Kumari }
789d3ae10eSAlpana Kumari 
7957e8c9beSAlpana Kumari /*
8057e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
8157e8c9beSAlpana Kumari  *
8257e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
8357e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
8457e8c9beSAlpana Kumari  *
8557e8c9beSAlpana Kumari  * @return None.
8657e8c9beSAlpana Kumari  */
871e1e598dSJonathan Doman inline void
881e1e598dSJonathan Doman     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
891e1e598dSJonathan Doman                            bool isCpuPresent)
9057e8c9beSAlpana Kumari {
911e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
9257e8c9beSAlpana Kumari 
9355f79e6fSEd Tanous     if (isCpuPresent)
9457e8c9beSAlpana Kumari     {
95b4b9595aSJames Feist         nlohmann::json& procCount =
96b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
9755f79e6fSEd Tanous         auto* procCountPtr =
98b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
99b4b9595aSJames Feist         if (procCountPtr != nullptr)
100b4b9595aSJames Feist         {
101b4b9595aSJames Feist             // shouldn't be possible to be nullptr
102b4b9595aSJames Feist             *procCountPtr += 1;
10357e8c9beSAlpana Kumari         }
104b4b9595aSJames Feist     }
10557e8c9beSAlpana Kumari }
10657e8c9beSAlpana Kumari 
10757e8c9beSAlpana Kumari /*
10857e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
10957e8c9beSAlpana Kumari  *        CPU Functional State
11057e8c9beSAlpana Kumari  *
11157e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
11257e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
11357e8c9beSAlpana Kumari  *
11457e8c9beSAlpana Kumari  * @return None.
11557e8c9beSAlpana Kumari  */
1161e1e598dSJonathan Doman inline void
1171e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1181e1e598dSJonathan Doman                              bool isCpuFunctional)
11957e8c9beSAlpana Kumari {
1201e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
12157e8c9beSAlpana Kumari 
12202cad96eSEd Tanous     const nlohmann::json& prevProcState =
12357e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
12457e8c9beSAlpana Kumari 
12557e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
12657e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
12757e8c9beSAlpana Kumari     // Functional.
12857e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
12957e8c9beSAlpana Kumari     {
130e05aec50SEd Tanous         if (isCpuFunctional)
13157e8c9beSAlpana Kumari         {
13257e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
13357e8c9beSAlpana Kumari                 "Enabled";
13457e8c9beSAlpana Kumari         }
13557e8c9beSAlpana Kumari     }
13657e8c9beSAlpana Kumari }
13757e8c9beSAlpana Kumari 
138382d6475SAli Ahmed inline void getProcessorProperties(
139382d6475SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
140382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
141382d6475SAli Ahmed         properties)
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 {
1885e7e2dc5SEd Tanous     auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3,
189382d6475SAli Ahmed                                        const bool cpuPresenceCheck) {
190382d6475SAli Ahmed         if (ec3)
191382d6475SAli Ahmed         {
192382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
193382d6475SAli Ahmed             return;
194382d6475SAli Ahmed         }
195382d6475SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
196382d6475SAli Ahmed     };
197382d6475SAli Ahmed 
1985e7e2dc5SEd Tanous     auto getCpuFunctionalState = [aResp](const boost::system::error_code& ec3,
199382d6475SAli Ahmed                                          const bool cpuFunctionalCheck) {
200382d6475SAli Ahmed         if (ec3)
201382d6475SAli Ahmed         {
202382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
203382d6475SAli Ahmed             return;
204382d6475SAli Ahmed         }
205382d6475SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
206382d6475SAli Ahmed     };
207382d6475SAli Ahmed 
208382d6475SAli Ahmed     // Get the Presence of CPU
209382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
210382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
211382d6475SAli Ahmed         "xyz.openbmc_project.Inventory.Item", "Present",
212382d6475SAli Ahmed         std::move(getCpuPresenceState));
213382d6475SAli Ahmed 
214382d6475SAli Ahmed     // Get the Functional State
215382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
216382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
217382d6475SAli Ahmed         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
218382d6475SAli Ahmed         std::move(getCpuFunctionalState));
219382d6475SAli Ahmed 
220bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
221bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
222bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
22303fbed92SAli Ahmed         [aResp, service,
2245e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
225b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
22603fbed92SAli Ahmed         if (ec2)
22703fbed92SAli Ahmed         {
22803fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
22903fbed92SAli Ahmed             messages::internalError(aResp->res);
23003fbed92SAli Ahmed             return;
23103fbed92SAli Ahmed         }
232382d6475SAli Ahmed         getProcessorProperties(aResp, properties);
233bc1d29deSKrzysztof Grobelny         });
23403fbed92SAli Ahmed }
23503fbed92SAli Ahmed 
23657e8c9beSAlpana Kumari /*
237c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
238c5b2abe0SLewanczyk, Dawid  *
239c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2408f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
241c5b2abe0SLewanczyk, Dawid  *
242c5b2abe0SLewanczyk, Dawid  * @return None.
243c5b2abe0SLewanczyk, Dawid  */
244b5a76932SEd Tanous inline void
2458d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
246b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2471abe55efSEd Tanous {
24855c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
249e99073f5SGeorge Liu     constexpr std::array<std::string_view, 5> interfaces = {
250e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Decorator.Asset",
251e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Cpu",
252e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
253e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System",
254e99073f5SGeorge Liu         "xyz.openbmc_project.Common.UUID",
255e99073f5SGeorge Liu     };
256e99073f5SGeorge Liu     dbus::utility::getSubTree(
257e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
258b9d36b47SEd Tanous         [aResp,
259e99073f5SGeorge Liu          systemHealth](const boost::system::error_code& ec,
260b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
2611abe55efSEd Tanous         if (ec)
2621abe55efSEd Tanous         {
26355c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
264f12894f8SJason M. Bills             messages::internalError(aResp->res);
265c5b2abe0SLewanczyk, Dawid             return;
266c5b2abe0SLewanczyk, Dawid         }
267c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
268002d39b4SEd Tanous         for (const std::pair<
269002d39b4SEd Tanous                  std::string,
270002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
2711214b7e7SGunnar Mills                  object : subtree)
2721abe55efSEd Tanous         {
273c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
27455c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
275002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
2761214b7e7SGunnar Mills                 connectionNames = object.second;
27726f6976fSEd Tanous             if (connectionNames.empty())
2781abe55efSEd Tanous             {
279c5b2abe0SLewanczyk, Dawid                 continue;
280c5b2abe0SLewanczyk, Dawid             }
281029573d4SEd Tanous 
2825bc2dc8eSJames Feist             auto memoryHealth = std::make_shared<HealthPopulate>(
283dfababfcSNan Zhou                 aResp, "/MemorySummary/Status"_json_pointer);
2845bc2dc8eSJames Feist 
2855bc2dc8eSJames Feist             auto cpuHealth = std::make_shared<HealthPopulate>(
286dfababfcSNan Zhou                 aResp, "/ProcessorSummary/Status"_json_pointer);
2875bc2dc8eSJames Feist 
2885bc2dc8eSJames Feist             systemHealth->children.emplace_back(memoryHealth);
2895bc2dc8eSJames Feist             systemHealth->children.emplace_back(cpuHealth);
2905bc2dc8eSJames Feist 
2916c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
2926c34de48SEd Tanous             // BiosVer
29304a258f4SEd Tanous             for (const auto& connection : connectionNames)
2941abe55efSEd Tanous             {
29504a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
2961abe55efSEd Tanous                 {
29704a258f4SEd Tanous                     if (interfaceName ==
29804a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
2991abe55efSEd Tanous                     {
3001abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
30104a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
3029d3ae10eSAlpana Kumari 
303bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
304bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
305bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Inventory.Item.Dimm",
3069d3ae10eSAlpana Kumari                             [aResp, service{connection.first},
3075e7e2dc5SEd Tanous                              path](const boost::system::error_code& ec2,
308b9d36b47SEd Tanous                                    const dbus::utility::DBusPropertiesMap&
3091214b7e7SGunnar Mills                                        properties) {
310cb13a392SEd Tanous                             if (ec2)
3111abe55efSEd Tanous                             {
312002d39b4SEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error "
313002d39b4SEd Tanous                                                  << ec2;
314f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
315c5b2abe0SLewanczyk, Dawid                                 return;
316c5b2abe0SLewanczyk, Dawid                             }
317002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
318c5b2abe0SLewanczyk, Dawid                                              << " Dimm properties.";
3199d3ae10eSAlpana Kumari 
320bc1d29deSKrzysztof Grobelny                             if (properties.empty())
3219d3ae10eSAlpana Kumari                             {
3221e1e598dSJonathan Doman                                 sdbusplus::asio::getProperty<bool>(
323002d39b4SEd Tanous                                     *crow::connections::systemBus, service,
324002d39b4SEd Tanous                                     path,
3251e1e598dSJonathan Doman                                     "xyz.openbmc_project.State."
3261e1e598dSJonathan Doman                                     "Decorator.OperationalStatus",
3271e1e598dSJonathan Doman                                     "Functional",
3285e7e2dc5SEd Tanous                                     [aResp](
3295e7e2dc5SEd Tanous                                         const boost::system::error_code& ec3,
3301e1e598dSJonathan Doman                                         bool dimmState) {
331cb13a392SEd Tanous                                     if (ec3)
3329d3ae10eSAlpana Kumari                                     {
3339d3ae10eSAlpana Kumari                                         BMCWEB_LOG_ERROR
334002d39b4SEd Tanous                                             << "DBUS response error " << ec3;
3359d3ae10eSAlpana Kumari                                         return;
3369d3ae10eSAlpana Kumari                                     }
337002d39b4SEd Tanous                                     updateDimmProperties(aResp, dimmState);
3381e1e598dSJonathan Doman                                     });
339bc1d29deSKrzysztof Grobelny                                 return;
3409d3ae10eSAlpana Kumari                             }
341bc1d29deSKrzysztof Grobelny 
342bc1d29deSKrzysztof Grobelny                             const uint32_t* memorySizeInKB = nullptr;
343bc1d29deSKrzysztof Grobelny 
344bc1d29deSKrzysztof Grobelny                             const bool success =
345bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
346bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
347bc1d29deSKrzysztof Grobelny                                     properties, "MemorySizeInKB",
348bc1d29deSKrzysztof Grobelny                                     memorySizeInKB);
349bc1d29deSKrzysztof Grobelny 
350bc1d29deSKrzysztof Grobelny                             if (!success)
351bc1d29deSKrzysztof Grobelny                             {
352bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
353bc1d29deSKrzysztof Grobelny                                 return;
354bc1d29deSKrzysztof Grobelny                             }
355bc1d29deSKrzysztof Grobelny 
356bc1d29deSKrzysztof Grobelny                             if (memorySizeInKB != nullptr)
357bc1d29deSKrzysztof Grobelny                             {
358bc1d29deSKrzysztof Grobelny                                 nlohmann::json& totalMemory =
359bc1d29deSKrzysztof Grobelny                                     aResp->res
360bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
361bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"];
362bc1d29deSKrzysztof Grobelny                                 const uint64_t* preValue =
363bc1d29deSKrzysztof Grobelny                                     totalMemory.get_ptr<const uint64_t*>();
364bc1d29deSKrzysztof Grobelny                                 if (preValue == nullptr)
365bc1d29deSKrzysztof Grobelny                                 {
366bc1d29deSKrzysztof Grobelny                                     aResp->res
367bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
368bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
369bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024);
370bc1d29deSKrzysztof Grobelny                                 }
371bc1d29deSKrzysztof Grobelny                                 else
372bc1d29deSKrzysztof Grobelny                                 {
373bc1d29deSKrzysztof Grobelny                                     aResp->res
374bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
375bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
376bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024) +
377bc1d29deSKrzysztof Grobelny                                         *preValue;
378bc1d29deSKrzysztof Grobelny                                 }
379bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["MemorySummary"]["Status"]
380bc1d29deSKrzysztof Grobelny                                                     ["State"] = "Enabled";
381bc1d29deSKrzysztof Grobelny                             }
382bc1d29deSKrzysztof Grobelny                             });
3835bc2dc8eSJames Feist 
3845bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
3851abe55efSEd Tanous                     }
38604a258f4SEd Tanous                     else if (interfaceName ==
38704a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
3881abe55efSEd Tanous                     {
3891abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
39004a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
39157e8c9beSAlpana Kumari 
39203fbed92SAli Ahmed                         getProcessorSummary(aResp, connection.first, path);
3935bc2dc8eSJames Feist 
3945bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
3951abe55efSEd Tanous                     }
396002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
3971abe55efSEd Tanous                     {
3981abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
39904a258f4SEd Tanous                             << "Found UUID, now get its properties.";
400bc1d29deSKrzysztof Grobelny 
401bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
402bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
403bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
4045e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec3,
405b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4061214b7e7SGunnar Mills                                         properties) {
407cb13a392SEd Tanous                             if (ec3)
4081abe55efSEd Tanous                             {
409002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
410002d39b4SEd Tanous                                                  << ec3;
411f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
412c5b2abe0SLewanczyk, Dawid                                 return;
413c5b2abe0SLewanczyk, Dawid                             }
414002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
415c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
41604a258f4SEd Tanous 
417bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
418bc1d29deSKrzysztof Grobelny 
419bc1d29deSKrzysztof Grobelny                             const bool success =
420bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
421bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
422bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
423bc1d29deSKrzysztof Grobelny 
424bc1d29deSKrzysztof Grobelny                             if (!success)
4251abe55efSEd Tanous                             {
426bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
427bc1d29deSKrzysztof Grobelny                                 return;
428bc1d29deSKrzysztof Grobelny                             }
429bc1d29deSKrzysztof Grobelny 
430bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
431bc1d29deSKrzysztof Grobelny                             {
432bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
43304a258f4SEd Tanous                                 if (valueStr.size() == 32)
4341abe55efSEd Tanous                                 {
435029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
436029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
437029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
438029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
43904a258f4SEd Tanous                                 }
440bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
441002d39b4SEd Tanous                                 aResp->res.jsonValue["UUID"] = valueStr;
442c5b2abe0SLewanczyk, Dawid                             }
443bc1d29deSKrzysztof Grobelny                             });
444c5b2abe0SLewanczyk, Dawid                     }
445029573d4SEd Tanous                     else if (interfaceName ==
446029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4471abe55efSEd Tanous                     {
448bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
449bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
450bc1d29deSKrzysztof Grobelny                             path,
451bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
4525e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
453b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4541214b7e7SGunnar Mills                                         propertiesList) {
455cb13a392SEd Tanous                             if (ec2)
456029573d4SEd Tanous                             {
457e4a4b9a9SJames Feist                                 // doesn't have to include this
458e4a4b9a9SJames Feist                                 // interface
459029573d4SEd Tanous                                 return;
460029573d4SEd Tanous                             }
461002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
462029573d4SEd Tanous                                              << " properties for system";
463bc1d29deSKrzysztof Grobelny 
464bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
465bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
466bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
467bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
468bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
469bc1d29deSKrzysztof Grobelny 
470bc1d29deSKrzysztof Grobelny                             const bool success =
471bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
472bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
473bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
474bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
475bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
476bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
477bc1d29deSKrzysztof Grobelny 
478bc1d29deSKrzysztof Grobelny                             if (!success)
479029573d4SEd Tanous                             {
480bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
481bc1d29deSKrzysztof Grobelny                                 return;
482029573d4SEd Tanous                             }
483bc1d29deSKrzysztof Grobelny 
484bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
485bc1d29deSKrzysztof Grobelny                             {
486bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["PartNumber"] =
487bc1d29deSKrzysztof Grobelny                                     *partNumber;
488029573d4SEd Tanous                             }
489bc1d29deSKrzysztof Grobelny 
490bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
491bc1d29deSKrzysztof Grobelny                             {
492bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SerialNumber"] =
493bc1d29deSKrzysztof Grobelny                                     *serialNumber;
494bc1d29deSKrzysztof Grobelny                             }
495bc1d29deSKrzysztof Grobelny 
496bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
497bc1d29deSKrzysztof Grobelny                             {
498bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Manufacturer"] =
499bc1d29deSKrzysztof Grobelny                                     *manufacturer;
500bc1d29deSKrzysztof Grobelny                             }
501bc1d29deSKrzysztof Grobelny 
502bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
503bc1d29deSKrzysztof Grobelny                             {
504bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Model"] = *model;
505bc1d29deSKrzysztof Grobelny                             }
506bc1d29deSKrzysztof Grobelny 
507bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
508bc1d29deSKrzysztof Grobelny                             {
509bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SubModel"] = *subModel;
510fc5afcf9Sbeccabroek                             }
511c1e236a6SGunnar Mills 
512cb7e1e7bSAndrew Geissler                             // Grab the bios version
513eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
514eee0013eSWilly Tu                                 aResp, sw_util::biosPurpose, "BiosVersion",
515002d39b4SEd Tanous                                 false);
516bc1d29deSKrzysztof Grobelny                             });
517e4a4b9a9SJames Feist 
5181e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5191e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5201e1e598dSJonathan Doman                             path,
5211e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5221e1e598dSJonathan Doman                             "AssetTag",
5231e1e598dSJonathan Doman                             "AssetTag",
5245e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
5251e1e598dSJonathan Doman                                     const std::string& value) {
526cb13a392SEd Tanous                             if (ec2)
527e4a4b9a9SJames Feist                             {
528e4a4b9a9SJames Feist                                 // doesn't have to include this
529e4a4b9a9SJames Feist                                 // interface
530e4a4b9a9SJames Feist                                 return;
531e4a4b9a9SJames Feist                             }
532e4a4b9a9SJames Feist 
5331e1e598dSJonathan Doman                             aResp->res.jsonValue["AssetTag"] = value;
5341e1e598dSJonathan Doman                             });
535029573d4SEd Tanous                     }
536029573d4SEd Tanous                 }
537029573d4SEd Tanous             }
538c5b2abe0SLewanczyk, Dawid         }
5396617338dSEd Tanous         });
540c5b2abe0SLewanczyk, Dawid }
541c5b2abe0SLewanczyk, Dawid 
542c5b2abe0SLewanczyk, Dawid /**
543c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
544c5b2abe0SLewanczyk, Dawid  *
545c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
546c5b2abe0SLewanczyk, Dawid  *
547c5b2abe0SLewanczyk, Dawid  * @return None.
548c5b2abe0SLewanczyk, Dawid  */
5498d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5501abe55efSEd Tanous {
55155c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5521e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5531e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5541e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5551e1e598dSJonathan Doman         "CurrentHostState",
5565e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
5571e1e598dSJonathan Doman                 const std::string& hostState) {
5581abe55efSEd Tanous         if (ec)
5591abe55efSEd Tanous         {
56022228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
56122228c28SAndrew Geissler             {
56222228c28SAndrew Geissler                 // Service not available, no error, just don't return
56322228c28SAndrew Geissler                 // host state info
56422228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
56522228c28SAndrew Geissler                 return;
56622228c28SAndrew Geissler             }
56722228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
568f12894f8SJason M. Bills             messages::internalError(aResp->res);
569c5b2abe0SLewanczyk, Dawid             return;
570c5b2abe0SLewanczyk, Dawid         }
5716617338dSEd Tanous 
5721e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
573c5b2abe0SLewanczyk, Dawid         // Verify Host State
5741e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5751abe55efSEd Tanous         {
57655c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "On";
5776617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Enabled";
5781abe55efSEd Tanous         }
5791e1e598dSJonathan Doman         else if (hostState ==
5800fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
5818c888608SGunnar Mills         {
5828c888608SGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
5838c888608SGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Quiesced";
5848c888608SGunnar Mills         }
5851e1e598dSJonathan Doman         else if (hostState ==
5860fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
58783935af9SAndrew Geissler         {
58883935af9SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "On";
58983935af9SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "InTest";
59083935af9SAndrew Geissler         }
5910fda0f12SGeorge Liu         else if (
5921e1e598dSJonathan Doman             hostState ==
5930fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5941a2a1437SAndrew Geissler         {
5951a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOn";
59615c27bf8SNoah Brewer             aResp->res.jsonValue["Status"]["State"] = "Starting";
5971a2a1437SAndrew Geissler         }
598002d39b4SEd Tanous         else if (hostState ==
5990fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6001a2a1437SAndrew Geissler         {
6011a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOff";
6021a2a1437SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "Disabled";
6031a2a1437SAndrew Geissler         }
6041abe55efSEd Tanous         else
6051abe55efSEd Tanous         {
60655c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "Off";
6076617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Disabled";
608c5b2abe0SLewanczyk, Dawid         }
6091e1e598dSJonathan Doman         });
610c5b2abe0SLewanczyk, Dawid }
611c5b2abe0SLewanczyk, Dawid 
612c5b2abe0SLewanczyk, Dawid /**
613786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
614491d8ee7SSantosh Puranik  *
615491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
616491d8ee7SSantosh Puranik  *
617491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
618491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
619491d8ee7SSantosh Puranik  */
62023a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
621491d8ee7SSantosh Puranik {
622491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
623491d8ee7SSantosh Puranik     {
624491d8ee7SSantosh Puranik         return "None";
625491d8ee7SSantosh Puranik     }
6263174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
627491d8ee7SSantosh Puranik     {
628491d8ee7SSantosh Puranik         return "Hdd";
629491d8ee7SSantosh Puranik     }
6303174e4dfSEd Tanous     if (dbusSource ==
631a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
632491d8ee7SSantosh Puranik     {
633491d8ee7SSantosh Puranik         return "Cd";
634491d8ee7SSantosh Puranik     }
6353174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
636491d8ee7SSantosh Puranik     {
637491d8ee7SSantosh Puranik         return "Pxe";
638491d8ee7SSantosh Puranik     }
6393174e4dfSEd Tanous     if (dbusSource ==
640944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6419f16b2c1SJennifer Lee     {
6429f16b2c1SJennifer Lee         return "Usb";
6439f16b2c1SJennifer Lee     }
644491d8ee7SSantosh Puranik     return "";
645491d8ee7SSantosh Puranik }
646491d8ee7SSantosh Puranik 
647491d8ee7SSantosh Puranik /**
648cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
649cd9a4666SKonstantin Aladyshev  *
650cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
651cd9a4666SKonstantin Aladyshev  *
652cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
653cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
654cd9a4666SKonstantin Aladyshev  */
655cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
656cd9a4666SKonstantin Aladyshev {
657cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
658cd9a4666SKonstantin Aladyshev     {
659cd9a4666SKonstantin Aladyshev         return "Legacy";
660cd9a4666SKonstantin Aladyshev     }
661cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
662cd9a4666SKonstantin Aladyshev     {
663cd9a4666SKonstantin Aladyshev         return "UEFI";
664cd9a4666SKonstantin Aladyshev     }
665cd9a4666SKonstantin Aladyshev     return "";
666cd9a4666SKonstantin Aladyshev }
667cd9a4666SKonstantin Aladyshev 
668cd9a4666SKonstantin Aladyshev /**
669786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
670491d8ee7SSantosh Puranik  *
671491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
672491d8ee7SSantosh Puranik  *
673491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
674491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
675491d8ee7SSantosh Puranik  */
67623a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
677491d8ee7SSantosh Puranik {
678491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
679491d8ee7SSantosh Puranik     {
680491d8ee7SSantosh Puranik         return "None";
681491d8ee7SSantosh Puranik     }
6823174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
683491d8ee7SSantosh Puranik     {
684491d8ee7SSantosh Puranik         return "Diags";
685491d8ee7SSantosh Puranik     }
6863174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
687491d8ee7SSantosh Puranik     {
688491d8ee7SSantosh Puranik         return "BiosSetup";
689491d8ee7SSantosh Puranik     }
690491d8ee7SSantosh Puranik     return "";
691491d8ee7SSantosh Puranik }
692491d8ee7SSantosh Puranik 
693491d8ee7SSantosh Puranik /**
694e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
695e43914b3SAndrew Geissler  *
696e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
697e43914b3SAndrew Geissler  *
698e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
699e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
700e43914b3SAndrew Geissler  */
701e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
702e43914b3SAndrew Geissler {
703e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
704e43914b3SAndrew Geissler     // enum
705e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
706e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
707e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
708e43914b3SAndrew Geissler     {
709e43914b3SAndrew Geissler         rfBpLastState = "None";
710e43914b3SAndrew Geissler     }
711e43914b3SAndrew Geissler     else if (dbusBootProgress ==
712e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
713e43914b3SAndrew Geissler              "PrimaryProcInit")
714e43914b3SAndrew Geissler     {
715e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
716e43914b3SAndrew Geissler     }
717e43914b3SAndrew Geissler     else if (dbusBootProgress ==
718e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
719e43914b3SAndrew Geissler              "BusInit")
720e43914b3SAndrew Geissler     {
721e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
722e43914b3SAndrew Geissler     }
723e43914b3SAndrew Geissler     else if (dbusBootProgress ==
724e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
725e43914b3SAndrew Geissler              "MemoryInit")
726e43914b3SAndrew Geissler     {
727e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
728e43914b3SAndrew Geissler     }
729e43914b3SAndrew Geissler     else if (dbusBootProgress ==
730e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
731e43914b3SAndrew Geissler              "SecondaryProcInit")
732e43914b3SAndrew Geissler     {
733e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
734e43914b3SAndrew Geissler     }
735e43914b3SAndrew Geissler     else if (dbusBootProgress ==
736e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
737e43914b3SAndrew Geissler              "PCIInit")
738e43914b3SAndrew Geissler     {
739e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
740e43914b3SAndrew Geissler     }
741e43914b3SAndrew Geissler     else if (dbusBootProgress ==
742e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
743e43914b3SAndrew Geissler              "SystemSetup")
744e43914b3SAndrew Geissler     {
745e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
746e43914b3SAndrew Geissler     }
747e43914b3SAndrew Geissler     else if (dbusBootProgress ==
748e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
749e43914b3SAndrew Geissler              "SystemInitComplete")
750e43914b3SAndrew Geissler     {
751e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
752e43914b3SAndrew Geissler     }
753e43914b3SAndrew Geissler     else if (dbusBootProgress ==
754e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
755e43914b3SAndrew Geissler              "OSStart")
756e43914b3SAndrew Geissler     {
757e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
758e43914b3SAndrew Geissler     }
759e43914b3SAndrew Geissler     else if (dbusBootProgress ==
760e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
761e43914b3SAndrew Geissler              "OSRunning")
762e43914b3SAndrew Geissler     {
763e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
764e43914b3SAndrew Geissler     }
765e43914b3SAndrew Geissler     else
766e43914b3SAndrew Geissler     {
767e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
768e43914b3SAndrew Geissler                          << dbusBootProgress;
769e43914b3SAndrew Geissler         // Just return the default
770e43914b3SAndrew Geissler     }
771e43914b3SAndrew Geissler     return rfBpLastState;
772e43914b3SAndrew Geissler }
773e43914b3SAndrew Geissler 
774e43914b3SAndrew Geissler /**
775786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
776491d8ee7SSantosh Puranik  *
777491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
778944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
779944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
780491d8ee7SSantosh Puranik  *
781944ffaf9SJohnathan Mantey  * @return Integer error code.
782491d8ee7SSantosh Puranik  */
7838d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
784944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
785944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
786491d8ee7SSantosh Puranik {
787c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
788c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
789944ffaf9SJohnathan Mantey 
790491d8ee7SSantosh Puranik     if (rfSource == "None")
791491d8ee7SSantosh Puranik     {
792944ffaf9SJohnathan Mantey         return 0;
793491d8ee7SSantosh Puranik     }
7943174e4dfSEd Tanous     if (rfSource == "Pxe")
795491d8ee7SSantosh Puranik     {
796944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
797944ffaf9SJohnathan Mantey     }
798944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
799944ffaf9SJohnathan Mantey     {
800944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
801944ffaf9SJohnathan Mantey     }
802944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
803944ffaf9SJohnathan Mantey     {
804944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
805944ffaf9SJohnathan Mantey     }
806944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
807944ffaf9SJohnathan Mantey     {
808944ffaf9SJohnathan Mantey         bootSource =
809944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
810944ffaf9SJohnathan Mantey     }
811944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
812944ffaf9SJohnathan Mantey     {
813944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
814491d8ee7SSantosh Puranik     }
8159f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8169f16b2c1SJennifer Lee     {
817944ffaf9SJohnathan Mantey         bootSource =
818944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8199f16b2c1SJennifer Lee     }
820491d8ee7SSantosh Puranik     else
821491d8ee7SSantosh Puranik     {
8220fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8230fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
824944ffaf9SJohnathan Mantey             << bootSource;
825944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
826944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
827944ffaf9SJohnathan Mantey         return -1;
828491d8ee7SSantosh Puranik     }
829944ffaf9SJohnathan Mantey     return 0;
830491d8ee7SSantosh Puranik }
8311981771bSAli Ahmed 
832978b8803SAndrew Geissler /**
833978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
834978b8803SAndrew Geissler  *
835978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
836978b8803SAndrew Geissler  *
837978b8803SAndrew Geissler  * @return None.
838978b8803SAndrew Geissler  */
8398d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
840978b8803SAndrew Geissler {
8411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8421e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8431e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8441e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
8455e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
8461e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
847978b8803SAndrew Geissler         if (ec)
848978b8803SAndrew Geissler         {
849978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
850978b8803SAndrew Geissler             // not found
851978b8803SAndrew Geissler             return;
852978b8803SAndrew Geissler         }
853978b8803SAndrew Geissler 
8541e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
855978b8803SAndrew Geissler 
856e43914b3SAndrew Geissler         aResp->res.jsonValue["BootProgress"]["LastState"] =
857e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8581e1e598dSJonathan Doman         });
859978b8803SAndrew Geissler }
860491d8ee7SSantosh Puranik 
861491d8ee7SSantosh Puranik /**
862b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
863b6d5d45cSHieu Huynh  *
864b6d5d45cSHieu Huynh  * @param[in] aResp  Shared pointer for generating response message.
865b6d5d45cSHieu Huynh  *
866b6d5d45cSHieu Huynh  * @return None.
867b6d5d45cSHieu Huynh  */
868b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
869b6d5d45cSHieu Huynh     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
870b6d5d45cSHieu Huynh {
871b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
872b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
873b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
874b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
8755e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
876b6d5d45cSHieu Huynh                 const uint64_t lastStateTime) {
877b6d5d45cSHieu Huynh         if (ec)
878b6d5d45cSHieu Huynh         {
879b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
880b6d5d45cSHieu Huynh             return;
881b6d5d45cSHieu Huynh         }
882b6d5d45cSHieu Huynh 
883b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
884b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
885b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
886b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
887b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
888b6d5d45cSHieu Huynh 
889b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
890b6d5d45cSHieu Huynh         aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
891b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
892b6d5d45cSHieu Huynh         });
893b6d5d45cSHieu Huynh }
894b6d5d45cSHieu Huynh 
895b6d5d45cSHieu Huynh /**
896c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
897cd9a4666SKonstantin Aladyshev  *
898cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
899cd9a4666SKonstantin Aladyshev  *
900cd9a4666SKonstantin Aladyshev  * @return None.
901cd9a4666SKonstantin Aladyshev  */
902cd9a4666SKonstantin Aladyshev 
903c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
904cd9a4666SKonstantin Aladyshev {
9051e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9061e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9071e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9081e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
9095e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9101e1e598dSJonathan Doman                 const std::string& bootType) {
911cd9a4666SKonstantin Aladyshev         if (ec)
912cd9a4666SKonstantin Aladyshev         {
913cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
914cd9a4666SKonstantin Aladyshev             return;
915cd9a4666SKonstantin Aladyshev         }
916cd9a4666SKonstantin Aladyshev 
9171e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
918cd9a4666SKonstantin Aladyshev 
919002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
920002d39b4SEd Tanous                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
921613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
922cd9a4666SKonstantin Aladyshev 
9231e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
924cd9a4666SKonstantin Aladyshev         if (rfType.empty())
925cd9a4666SKonstantin Aladyshev         {
926cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
927cd9a4666SKonstantin Aladyshev             return;
928cd9a4666SKonstantin Aladyshev         }
929cd9a4666SKonstantin Aladyshev 
930cd9a4666SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9311e1e598dSJonathan Doman         });
932cd9a4666SKonstantin Aladyshev }
933cd9a4666SKonstantin Aladyshev 
934cd9a4666SKonstantin Aladyshev /**
935c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
936491d8ee7SSantosh Puranik  *
937491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
938491d8ee7SSantosh Puranik  *
939491d8ee7SSantosh Puranik  * @return None.
940491d8ee7SSantosh Puranik  */
941c21865c4SKonstantin Aladyshev 
942c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
943491d8ee7SSantosh Puranik {
9441e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9451e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9461e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9471e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
9485e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9491e1e598dSJonathan Doman                 const std::string& bootModeStr) {
950491d8ee7SSantosh Puranik         if (ec)
951491d8ee7SSantosh Puranik         {
952491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
953491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
954491d8ee7SSantosh Puranik             return;
955491d8ee7SSantosh Puranik         }
956491d8ee7SSantosh Puranik 
9571e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
958491d8ee7SSantosh Puranik 
9590fda0f12SGeorge Liu         aResp->res
9600fda0f12SGeorge Liu             .jsonValue["Boot"]
961002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
962002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
963491d8ee7SSantosh Puranik 
9641e1e598dSJonathan Doman         if (bootModeStr !=
965491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
966491d8ee7SSantosh Puranik         {
9671e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
968491d8ee7SSantosh Puranik             if (!rfMode.empty())
969491d8ee7SSantosh Puranik             {
970491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
971491d8ee7SSantosh Puranik                     rfMode;
972491d8ee7SSantosh Puranik             }
973491d8ee7SSantosh Puranik         }
9741e1e598dSJonathan Doman         });
975491d8ee7SSantosh Puranik }
976491d8ee7SSantosh Puranik 
977491d8ee7SSantosh Puranik /**
978c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
979491d8ee7SSantosh Puranik  *
980491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
981491d8ee7SSantosh Puranik  *
982491d8ee7SSantosh Puranik  * @return None.
983491d8ee7SSantosh Puranik  */
984c21865c4SKonstantin Aladyshev 
985c21865c4SKonstantin Aladyshev inline void
986c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
987491d8ee7SSantosh Puranik {
9881e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9891e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9901e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9911e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
9925e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9931e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
994491d8ee7SSantosh Puranik         if (ec)
995491d8ee7SSantosh Puranik         {
996491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
9975ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
9985ef735c8SNan Zhou             {
9995ef735c8SNan Zhou                 return;
10005ef735c8SNan Zhou             }
1001491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1002491d8ee7SSantosh Puranik             return;
1003491d8ee7SSantosh Puranik         }
1004491d8ee7SSantosh Puranik 
10051e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1006491d8ee7SSantosh Puranik 
10071e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1008491d8ee7SSantosh Puranik         if (!rfSource.empty())
1009491d8ee7SSantosh Puranik         {
1010002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1011491d8ee7SSantosh Puranik         }
1012cd9a4666SKonstantin Aladyshev 
1013cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1014cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1015c21865c4SKonstantin Aladyshev         getBootOverrideMode(aResp);
10161e1e598dSJonathan Doman         });
1017491d8ee7SSantosh Puranik }
1018491d8ee7SSantosh Puranik 
1019491d8ee7SSantosh Puranik /**
1020c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1021c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1022c21865c4SKonstantin Aladyshev  * state
1023491d8ee7SSantosh Puranik  *
1024491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1025491d8ee7SSantosh Puranik  *
1026491d8ee7SSantosh Puranik  * @return None.
1027491d8ee7SSantosh Puranik  */
1028491d8ee7SSantosh Puranik 
1029c21865c4SKonstantin Aladyshev inline void
1030c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1031c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1032c21865c4SKonstantin Aladyshev {
1033c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1034c21865c4SKonstantin Aladyshev     {
1035c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1036c21865c4SKonstantin Aladyshev         return;
1037c21865c4SKonstantin Aladyshev     }
1038c21865c4SKonstantin Aladyshev 
1039c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1040c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10421e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10431e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10441e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10455e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1046491d8ee7SSantosh Puranik         if (ec)
1047491d8ee7SSantosh Puranik         {
1048491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1049c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1050491d8ee7SSantosh Puranik             return;
1051491d8ee7SSantosh Puranik         }
1052491d8ee7SSantosh Puranik 
1053c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1054c21865c4SKonstantin Aladyshev         {
1055002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1056c21865c4SKonstantin Aladyshev         }
1057c21865c4SKonstantin Aladyshev         else
1058c21865c4SKonstantin Aladyshev         {
1059c21865c4SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1060c21865c4SKonstantin Aladyshev                 "Continuous";
1061c21865c4SKonstantin Aladyshev         }
10621e1e598dSJonathan Doman         });
1063491d8ee7SSantosh Puranik }
1064491d8ee7SSantosh Puranik 
1065491d8ee7SSantosh Puranik /**
1066c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1067c21865c4SKonstantin Aladyshev  *
1068c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1069c21865c4SKonstantin Aladyshev  *
1070c21865c4SKonstantin Aladyshev  * @return None.
1071c21865c4SKonstantin Aladyshev  */
1072c21865c4SKonstantin Aladyshev 
1073c21865c4SKonstantin Aladyshev inline void
1074c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1075c21865c4SKonstantin Aladyshev {
10761e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10771e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10781e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10791e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10805e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
10811e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1082c21865c4SKonstantin Aladyshev         if (ec)
1083c21865c4SKonstantin Aladyshev         {
1084c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10855ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10865ef735c8SNan Zhou             {
10875ef735c8SNan Zhou                 return;
10885ef735c8SNan Zhou             }
1089c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1090c21865c4SKonstantin Aladyshev             return;
1091c21865c4SKonstantin Aladyshev         }
1092c21865c4SKonstantin Aladyshev 
10931e1e598dSJonathan Doman         processBootOverrideEnable(aResp, bootOverrideEnable);
10941e1e598dSJonathan Doman         });
1095c21865c4SKonstantin Aladyshev }
1096c21865c4SKonstantin Aladyshev 
1097c21865c4SKonstantin Aladyshev /**
1098c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1099c21865c4SKonstantin Aladyshev  *
1100c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1101c21865c4SKonstantin Aladyshev  *
1102c21865c4SKonstantin Aladyshev  * @return None.
1103c21865c4SKonstantin Aladyshev  */
1104c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1105c21865c4SKonstantin Aladyshev {
1106c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1107c21865c4SKonstantin Aladyshev 
1108c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1109c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1110c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1111c21865c4SKonstantin Aladyshev }
1112c21865c4SKonstantin Aladyshev 
1113c21865c4SKonstantin Aladyshev /**
1114c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1115c0557e1aSGunnar Mills  *
1116c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1117c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1118c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1119c0557e1aSGunnar Mills  * last power operation time.
1120c0557e1aSGunnar Mills  *
1121c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1122c0557e1aSGunnar Mills  *
1123c0557e1aSGunnar Mills  * @return None.
1124c0557e1aSGunnar Mills  */
11258d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1126c0557e1aSGunnar Mills {
1127c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1128c0557e1aSGunnar Mills 
11291e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11301e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11311e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11321e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
11335e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) {
1134c0557e1aSGunnar Mills         if (ec)
1135c0557e1aSGunnar Mills         {
1136c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1137c0557e1aSGunnar Mills             return;
1138c0557e1aSGunnar Mills         }
1139c0557e1aSGunnar Mills 
1140c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1141c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11421e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1143c0557e1aSGunnar Mills 
1144c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1145c0557e1aSGunnar Mills         aResp->res.jsonValue["LastResetTime"] =
11462b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11471e1e598dSJonathan Doman         });
1148c0557e1aSGunnar Mills }
1149c0557e1aSGunnar Mills 
1150c0557e1aSGunnar Mills /**
1151797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1152797d5daeSCorey Hardesty  *
1153797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1154797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1155797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1156797d5daeSCorey Hardesty  * dbus.
1157797d5daeSCorey Hardesty  *
1158797d5daeSCorey Hardesty  * @param[in] aResp     Shared pointer for generating response message.
1159797d5daeSCorey Hardesty  *
1160797d5daeSCorey Hardesty  * @return None.
1161797d5daeSCorey Hardesty  */
1162797d5daeSCorey Hardesty inline void
1163797d5daeSCorey Hardesty     getAutomaticRebootAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1164797d5daeSCorey Hardesty {
1165797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1166797d5daeSCorey Hardesty 
1167797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1168797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1169797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1170797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1171797d5daeSCorey Hardesty         [aResp{aResp}](const boost::system::error_code& ec,
1172797d5daeSCorey Hardesty                        const dbus::utility::DBusPropertiesMap& propertiesList) {
1173797d5daeSCorey Hardesty         if (ec)
1174797d5daeSCorey Hardesty         {
1175797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1176797d5daeSCorey Hardesty             {
1177797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1178797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1179797d5daeSCorey Hardesty             }
1180797d5daeSCorey Hardesty             return;
1181797d5daeSCorey Hardesty         }
1182797d5daeSCorey Hardesty 
1183797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1184797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1185797d5daeSCorey Hardesty 
1186797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1187797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1188797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1189797d5daeSCorey Hardesty 
1190797d5daeSCorey Hardesty         if (!success)
1191797d5daeSCorey Hardesty         {
1192797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1193797d5daeSCorey Hardesty             return;
1194797d5daeSCorey Hardesty         }
1195797d5daeSCorey Hardesty 
1196797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1197797d5daeSCorey Hardesty         {
1198797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1199797d5daeSCorey Hardesty                 *attemptsLeft;
1200797d5daeSCorey Hardesty         }
1201797d5daeSCorey Hardesty 
1202797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1203797d5daeSCorey Hardesty         {
1204797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1205797d5daeSCorey Hardesty                 *retryAttempts;
1206797d5daeSCorey Hardesty         }
1207797d5daeSCorey Hardesty         });
1208797d5daeSCorey Hardesty }
1209797d5daeSCorey Hardesty 
1210797d5daeSCorey Hardesty /**
12116bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12126bd5a8d2SGunnar Mills  *
12136bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
12146bd5a8d2SGunnar Mills  *
12156bd5a8d2SGunnar Mills  * @return None.
12166bd5a8d2SGunnar Mills  */
1217797d5daeSCorey Hardesty inline void
1218797d5daeSCorey Hardesty     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12196bd5a8d2SGunnar Mills {
12206bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12216bd5a8d2SGunnar Mills 
12221e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12231e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12241e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12251e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
12265e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) {
12276bd5a8d2SGunnar Mills         if (ec)
12286bd5a8d2SGunnar Mills         {
1229797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1230797d5daeSCorey Hardesty             {
1231797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1232797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1233797d5daeSCorey Hardesty             }
12346bd5a8d2SGunnar Mills             return;
12356bd5a8d2SGunnar Mills         }
12366bd5a8d2SGunnar Mills 
12371e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1238e05aec50SEd Tanous         if (autoRebootEnabled)
12396bd5a8d2SGunnar Mills         {
12406bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12416bd5a8d2SGunnar Mills                 "RetryAttempts";
12426bd5a8d2SGunnar Mills         }
12436bd5a8d2SGunnar Mills         else
12446bd5a8d2SGunnar Mills         {
1245002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
12466bd5a8d2SGunnar Mills         }
1247797d5daeSCorey Hardesty         getAutomaticRebootAttempts(aResp);
124869f35306SGunnar Mills 
124969f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
125069f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
125169f35306SGunnar Mills         // RetryAttempts.
1252002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
12530fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
12540fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
12551e1e598dSJonathan Doman         });
12566bd5a8d2SGunnar Mills }
12576bd5a8d2SGunnar Mills 
12586bd5a8d2SGunnar Mills /**
1259797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1260797d5daeSCorey Hardesty  *
1261797d5daeSCorey Hardesty  * @param[in] aResp   Shared pointer for generating response message.
1262797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1263797d5daeSCorey Hardesty  *
1264797d5daeSCorey Hardesty  *@return None.
1265797d5daeSCorey Hardesty  */
1266797d5daeSCorey Hardesty 
1267797d5daeSCorey Hardesty inline void
1268797d5daeSCorey Hardesty     setAutomaticRetryAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1269797d5daeSCorey Hardesty                               const uint32_t retryAttempts)
1270797d5daeSCorey Hardesty {
1271797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
1272797d5daeSCorey Hardesty     crow::connections::systemBus->async_method_call(
1273797d5daeSCorey Hardesty         [aResp](const boost::system::error_code& ec) {
1274797d5daeSCorey Hardesty         if (ec)
1275797d5daeSCorey Hardesty         {
1276797d5daeSCorey Hardesty             BMCWEB_LOG_ERROR
1277797d5daeSCorey Hardesty                 << "DBUS response error: Set setAutomaticRetryAttempts" << ec;
1278797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1279797d5daeSCorey Hardesty             return;
1280797d5daeSCorey Hardesty         }
1281797d5daeSCorey Hardesty         },
1282797d5daeSCorey Hardesty         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1283797d5daeSCorey Hardesty         "org.freedesktop.DBus.Properties", "Set",
1284797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1285797d5daeSCorey Hardesty         std::variant<uint32_t>(retryAttempts));
1286797d5daeSCorey Hardesty }
1287797d5daeSCorey Hardesty 
1288797d5daeSCorey Hardesty /**
1289c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1290c6a620f2SGeorge Liu  *
1291c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1292c6a620f2SGeorge Liu  *
1293c6a620f2SGeorge Liu  * @return None.
1294c6a620f2SGeorge Liu  */
12958d1b46d7Szhanghch05 inline void
12968d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1297c6a620f2SGeorge Liu {
1298c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1299c6a620f2SGeorge Liu 
13001e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13011e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13021e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13031e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
13045e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
13055e7e2dc5SEd Tanous                 const std::string& policy) {
1306c6a620f2SGeorge Liu         if (ec)
1307c6a620f2SGeorge Liu         {
1308c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1309c6a620f2SGeorge Liu             return;
1310c6a620f2SGeorge Liu         }
1311c6a620f2SGeorge Liu 
13120fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
13130fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1314c6a620f2SGeorge Liu              "AlwaysOn"},
13150fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1316c6a620f2SGeorge Liu              "AlwaysOff"},
13170fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
13184ed47cb8SMatthew Barth              "LastState"},
13194ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
13204ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
13214ed47cb8SMatthew Barth              "AlwaysOff"}};
1322c6a620f2SGeorge Liu 
13231e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1324c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1325c6a620f2SGeorge Liu         {
1326c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1327c6a620f2SGeorge Liu             return;
1328c6a620f2SGeorge Liu         }
1329c6a620f2SGeorge Liu 
1330c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
13311e1e598dSJonathan Doman         });
1332c6a620f2SGeorge Liu }
1333c6a620f2SGeorge Liu 
1334c6a620f2SGeorge Liu /**
13351981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13361981771bSAli Ahmed  * TPM is required for booting the host.
13371981771bSAli Ahmed  *
13381981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13391981771bSAli Ahmed  *
13401981771bSAli Ahmed  * @return None.
13411981771bSAli Ahmed  */
13421981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13431981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13441981771bSAli Ahmed {
13451981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1346e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1347e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1348e99073f5SGeorge Liu     dbus::utility::getSubTree(
1349e99073f5SGeorge Liu         "/", 0, interfaces,
1350e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1351b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
13521981771bSAli Ahmed         if (ec)
13531981771bSAli Ahmed         {
1354002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1355002d39b4SEd Tanous                              << ec;
13561981771bSAli Ahmed             // This is an optional D-Bus object so just return if
13571981771bSAli Ahmed             // error occurs
13581981771bSAli Ahmed             return;
13591981771bSAli Ahmed         }
136026f6976fSEd Tanous         if (subtree.empty())
13611981771bSAli Ahmed         {
13621981771bSAli Ahmed             // As noted above, this is an optional interface so just return
13631981771bSAli Ahmed             // if there is no instance found
13641981771bSAli Ahmed             return;
13651981771bSAli Ahmed         }
13661981771bSAli Ahmed 
13671981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
13681981771bSAli Ahmed         if (subtree.size() > 1)
13691981771bSAli Ahmed         {
13701981771bSAli Ahmed             BMCWEB_LOG_DEBUG
13711981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13721981771bSAli Ahmed                 << subtree.size();
13731981771bSAli Ahmed             // Throw an internal Error and return
13741981771bSAli Ahmed             messages::internalError(aResp->res);
13751981771bSAli Ahmed             return;
13761981771bSAli Ahmed         }
13771981771bSAli Ahmed 
13781981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13791981771bSAli Ahmed         // field
13801981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13811981771bSAli Ahmed         {
13821981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13831981771bSAli Ahmed             messages::internalError(aResp->res);
13841981771bSAli Ahmed             return;
13851981771bSAli Ahmed         }
13861981771bSAli Ahmed 
13871981771bSAli Ahmed         const std::string& path = subtree[0].first;
13881981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
13891981771bSAli Ahmed 
13901981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
13911e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
13921e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
13931e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
13945e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
13958a592810SEd Tanous             if (ec2)
13961981771bSAli Ahmed             {
1397002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
13988a592810SEd Tanous                                  << ec2;
13991981771bSAli Ahmed                 messages::internalError(aResp->res);
14001981771bSAli Ahmed                 return;
14011981771bSAli Ahmed             }
14021981771bSAli Ahmed 
14031e1e598dSJonathan Doman             if (tpmRequired)
14041981771bSAli Ahmed             {
1405002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14061981771bSAli Ahmed                     "Required";
14071981771bSAli Ahmed             }
14081981771bSAli Ahmed             else
14091981771bSAli Ahmed             {
1410002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14111981771bSAli Ahmed                     "Disabled";
14121981771bSAli Ahmed             }
14131e1e598dSJonathan Doman             });
1414e99073f5SGeorge Liu         });
14151981771bSAli Ahmed }
14161981771bSAli Ahmed 
14171981771bSAli Ahmed /**
14181c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14191c05dae3SAli Ahmed  * TPM is required for booting the host.
14201c05dae3SAli Ahmed  *
14211c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
14221c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14231c05dae3SAli Ahmed  *
14241c05dae3SAli Ahmed  * @return None.
14251c05dae3SAli Ahmed  */
14261c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
14271c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
14281c05dae3SAli Ahmed {
14291c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1430e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1431e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1432e99073f5SGeorge Liu     dbus::utility::getSubTree(
1433e99073f5SGeorge Liu         "/", 0, interfaces,
1434e99073f5SGeorge Liu         [aResp,
1435e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1436e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14371c05dae3SAli Ahmed         if (ec)
14381c05dae3SAli Ahmed         {
1439002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1440002d39b4SEd Tanous                              << ec;
14411c05dae3SAli Ahmed             messages::internalError(aResp->res);
14421c05dae3SAli Ahmed             return;
14431c05dae3SAli Ahmed         }
144426f6976fSEd Tanous         if (subtree.empty())
14451c05dae3SAli Ahmed         {
14461c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
14471c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
14481c05dae3SAli Ahmed             return;
14491c05dae3SAli Ahmed         }
14501c05dae3SAli Ahmed 
14511c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
14521c05dae3SAli Ahmed         if (subtree.size() > 1)
14531c05dae3SAli Ahmed         {
14541c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
14551c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
14561c05dae3SAli Ahmed                 << subtree.size();
14571c05dae3SAli Ahmed             // Throw an internal Error and return
14581c05dae3SAli Ahmed             messages::internalError(aResp->res);
14591c05dae3SAli Ahmed             return;
14601c05dae3SAli Ahmed         }
14611c05dae3SAli Ahmed 
14621c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14631c05dae3SAli Ahmed         // field
14641c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14651c05dae3SAli Ahmed         {
14661c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14671c05dae3SAli Ahmed             messages::internalError(aResp->res);
14681c05dae3SAli Ahmed             return;
14691c05dae3SAli Ahmed         }
14701c05dae3SAli Ahmed 
14711c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
14721c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14731c05dae3SAli Ahmed 
14741c05dae3SAli Ahmed         if (serv.empty())
14751c05dae3SAli Ahmed         {
14761c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
14771c05dae3SAli Ahmed             messages::internalError(aResp->res);
14781c05dae3SAli Ahmed             return;
14791c05dae3SAli Ahmed         }
14801c05dae3SAli Ahmed 
14811c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
14821c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
14835e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
14848a592810SEd Tanous             if (ec2)
14851c05dae3SAli Ahmed             {
14860fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
14870fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
14888a592810SEd Tanous                     << ec2;
14891c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14901c05dae3SAli Ahmed                 return;
14911c05dae3SAli Ahmed             }
14921c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
14931c05dae3SAli Ahmed             },
14941c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
14951c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1496168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
1497e99073f5SGeorge Liu         });
14981c05dae3SAli Ahmed }
14991c05dae3SAli Ahmed 
15001c05dae3SAli Ahmed /**
1501491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1502491d8ee7SSantosh Puranik  *
1503491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1504cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1505cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1506cd9a4666SKonstantin Aladyshev  */
1507cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1508cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1509cd9a4666SKonstantin Aladyshev {
1510c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1511cd9a4666SKonstantin Aladyshev 
1512c21865c4SKonstantin Aladyshev     if (!bootType)
1513cd9a4666SKonstantin Aladyshev     {
1514c21865c4SKonstantin Aladyshev         return;
1515c21865c4SKonstantin Aladyshev     }
1516c21865c4SKonstantin Aladyshev 
1517cd9a4666SKonstantin Aladyshev     // Source target specified
1518cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1519cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1520cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1521cd9a4666SKonstantin Aladyshev     {
1522cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1523cd9a4666SKonstantin Aladyshev     }
1524cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1525cd9a4666SKonstantin Aladyshev     {
1526cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1527cd9a4666SKonstantin Aladyshev     }
1528cd9a4666SKonstantin Aladyshev     else
1529cd9a4666SKonstantin Aladyshev     {
1530cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1531cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1532cd9a4666SKonstantin Aladyshev                          << *bootType;
1533cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1534cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1535cd9a4666SKonstantin Aladyshev         return;
1536cd9a4666SKonstantin Aladyshev     }
1537cd9a4666SKonstantin Aladyshev 
1538cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1539cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1540cd9a4666SKonstantin Aladyshev 
1541cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
15425e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1543cd9a4666SKonstantin Aladyshev         if (ec)
1544cd9a4666SKonstantin Aladyshev         {
1545cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1546cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1547cd9a4666SKonstantin Aladyshev             {
1548cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1549cd9a4666SKonstantin Aladyshev                 return;
1550cd9a4666SKonstantin Aladyshev             }
1551cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1552cd9a4666SKonstantin Aladyshev             return;
1553cd9a4666SKonstantin Aladyshev         }
1554cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1555cd9a4666SKonstantin Aladyshev         },
1556c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1557c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1558cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1559cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1560168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1561cd9a4666SKonstantin Aladyshev }
1562cd9a4666SKonstantin Aladyshev 
1563cd9a4666SKonstantin Aladyshev /**
1564cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1565cd9a4666SKonstantin Aladyshev  *
1566cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1567c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1568c21865c4SKonstantin Aladyshev  * @return Integer error code.
1569c21865c4SKonstantin Aladyshev  */
1570c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1571c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1572c21865c4SKonstantin Aladyshev {
1573c21865c4SKonstantin Aladyshev     if (!bootEnable)
1574c21865c4SKonstantin Aladyshev     {
1575c21865c4SKonstantin Aladyshev         return;
1576c21865c4SKonstantin Aladyshev     }
1577c21865c4SKonstantin Aladyshev     // Source target specified
1578c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1579c21865c4SKonstantin Aladyshev 
1580c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1581c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1582c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1583c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1584c21865c4SKonstantin Aladyshev     {
1585c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1586c21865c4SKonstantin Aladyshev     }
1587c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1588c21865c4SKonstantin Aladyshev     {
1589c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1590c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1591c21865c4SKonstantin Aladyshev     }
1592c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1593c21865c4SKonstantin Aladyshev     {
1594c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1595c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1596c21865c4SKonstantin Aladyshev     }
1597c21865c4SKonstantin Aladyshev     else
1598c21865c4SKonstantin Aladyshev     {
15990fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
16000fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1601c21865c4SKonstantin Aladyshev             << *bootEnable;
1602c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1603c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1604c21865c4SKonstantin Aladyshev         return;
1605c21865c4SKonstantin Aladyshev     }
1606c21865c4SKonstantin Aladyshev 
1607c21865c4SKonstantin Aladyshev     // Act on validated parameters
1608c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1609c21865c4SKonstantin Aladyshev 
1610c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16115e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec2) {
16128a592810SEd Tanous         if (ec2)
1613c21865c4SKonstantin Aladyshev         {
16148a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1615c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1616c21865c4SKonstantin Aladyshev             return;
1617c21865c4SKonstantin Aladyshev         }
1618c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1619c21865c4SKonstantin Aladyshev         },
1620c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1621c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1622c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1623c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1624168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1625c21865c4SKonstantin Aladyshev 
1626c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1627c21865c4SKonstantin Aladyshev     {
1628c21865c4SKonstantin Aladyshev         return;
1629c21865c4SKonstantin Aladyshev     }
1630c21865c4SKonstantin Aladyshev 
1631c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1632c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1633c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1634c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1635c21865c4SKonstantin Aladyshev 
1636c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16375e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1638c21865c4SKonstantin Aladyshev         if (ec)
1639c21865c4SKonstantin Aladyshev         {
1640c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1641c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1642c21865c4SKonstantin Aladyshev             return;
1643c21865c4SKonstantin Aladyshev         }
1644c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1645c21865c4SKonstantin Aladyshev         },
1646c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1647c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1648c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1649c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1650168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1651c21865c4SKonstantin Aladyshev }
1652c21865c4SKonstantin Aladyshev 
1653c21865c4SKonstantin Aladyshev /**
1654c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1655c21865c4SKonstantin Aladyshev  *
1656c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1657491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1658491d8ee7SSantosh Puranik  *
1659265c1602SJohnathan Mantey  * @return Integer error code.
1660491d8ee7SSantosh Puranik  */
1661cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1662cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1663491d8ee7SSantosh Puranik {
1664c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1665c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1666944ffaf9SJohnathan Mantey 
1667c21865c4SKonstantin Aladyshev     if (!bootSource)
1668491d8ee7SSantosh Puranik     {
1669c21865c4SKonstantin Aladyshev         return;
1670c21865c4SKonstantin Aladyshev     }
1671c21865c4SKonstantin Aladyshev 
1672491d8ee7SSantosh Puranik     // Source target specified
1673491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1674491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1675e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1676e662eae8SEd Tanous         0)
1677491d8ee7SSantosh Puranik     {
1678944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1679944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1680491d8ee7SSantosh Puranik             << *bootSource;
1681491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1682491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1683491d8ee7SSantosh Puranik         return;
1684491d8ee7SSantosh Puranik     }
1685491d8ee7SSantosh Puranik 
1686944ffaf9SJohnathan Mantey     // Act on validated parameters
1687944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1688944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1689944ffaf9SJohnathan Mantey 
1690491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
16915e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1692491d8ee7SSantosh Puranik         if (ec)
1693491d8ee7SSantosh Puranik         {
1694491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1695491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1696491d8ee7SSantosh Puranik             return;
1697491d8ee7SSantosh Puranik         }
1698491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1699491d8ee7SSantosh Puranik         },
1700c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1701c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1702491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1703491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1704168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1705944ffaf9SJohnathan Mantey 
1706491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
17075e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1708491d8ee7SSantosh Puranik         if (ec)
1709491d8ee7SSantosh Puranik         {
1710491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1711491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1712491d8ee7SSantosh Puranik             return;
1713491d8ee7SSantosh Puranik         }
1714491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1715491d8ee7SSantosh Puranik         },
1716c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1717c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1718491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1719491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1720168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1721cd9a4666SKonstantin Aladyshev }
1722944ffaf9SJohnathan Mantey 
1723cd9a4666SKonstantin Aladyshev /**
1724c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1725491d8ee7SSantosh Puranik  *
1726491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1727491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1728cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1729491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1730491d8ee7SSantosh Puranik  *
1731265c1602SJohnathan Mantey  * @return Integer error code.
1732491d8ee7SSantosh Puranik  */
1733c21865c4SKonstantin Aladyshev 
1734c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1735c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1736c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1737c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1738491d8ee7SSantosh Puranik {
1739491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1740491d8ee7SSantosh Puranik 
1741c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1742c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1743c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1744491d8ee7SSantosh Puranik }
1745491d8ee7SSantosh Puranik 
1746c6a620f2SGeorge Liu /**
174798e386ecSGunnar Mills  * @brief Sets AssetTag
174898e386ecSGunnar Mills  *
174998e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
175098e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
175198e386ecSGunnar Mills  *
175298e386ecSGunnar Mills  * @return None.
175398e386ecSGunnar Mills  */
17548d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
175598e386ecSGunnar Mills                         const std::string& assetTag)
175698e386ecSGunnar Mills {
1757e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1758e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1759e99073f5SGeorge Liu     dbus::utility::getSubTree(
1760e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1761b9d36b47SEd Tanous         [aResp,
1762e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1763b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
176498e386ecSGunnar Mills         if (ec)
176598e386ecSGunnar Mills         {
176698e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
176798e386ecSGunnar Mills             messages::internalError(aResp->res);
176898e386ecSGunnar Mills             return;
176998e386ecSGunnar Mills         }
177026f6976fSEd Tanous         if (subtree.empty())
177198e386ecSGunnar Mills         {
177298e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
177398e386ecSGunnar Mills             messages::internalError(aResp->res);
177498e386ecSGunnar Mills             return;
177598e386ecSGunnar Mills         }
177698e386ecSGunnar Mills         // Assume only 1 system D-Bus object
177798e386ecSGunnar Mills         // Throw an error if there is more than 1
177898e386ecSGunnar Mills         if (subtree.size() > 1)
177998e386ecSGunnar Mills         {
178098e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
178198e386ecSGunnar Mills             messages::internalError(aResp->res);
178298e386ecSGunnar Mills             return;
178398e386ecSGunnar Mills         }
178498e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
178598e386ecSGunnar Mills         {
178698e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
178798e386ecSGunnar Mills             messages::internalError(aResp->res);
178898e386ecSGunnar Mills             return;
178998e386ecSGunnar Mills         }
179098e386ecSGunnar Mills 
179198e386ecSGunnar Mills         const std::string& path = subtree[0].first;
179298e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
179398e386ecSGunnar Mills 
179498e386ecSGunnar Mills         if (service.empty())
179598e386ecSGunnar Mills         {
179698e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
179798e386ecSGunnar Mills             messages::internalError(aResp->res);
179898e386ecSGunnar Mills             return;
179998e386ecSGunnar Mills         }
180098e386ecSGunnar Mills 
180198e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
18025e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
180398e386ecSGunnar Mills             if (ec2)
180498e386ecSGunnar Mills             {
1805002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1806002d39b4SEd Tanous                                  << ec2;
180798e386ecSGunnar Mills                 messages::internalError(aResp->res);
180898e386ecSGunnar Mills                 return;
180998e386ecSGunnar Mills             }
181098e386ecSGunnar Mills             },
181198e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
181298e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1813168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
1814e99073f5SGeorge Liu         });
181598e386ecSGunnar Mills }
181698e386ecSGunnar Mills 
181798e386ecSGunnar Mills /**
181869f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
181969f35306SGunnar Mills  *
182069f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
182169f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
182269f35306SGunnar Mills  *
182369f35306SGunnar Mills  * @return None.
182469f35306SGunnar Mills  */
18258d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1826f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
182769f35306SGunnar Mills {
182869f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
182969f35306SGunnar Mills 
183069f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1831543f4400SEd Tanous     bool autoRebootEnabled = false;
183269f35306SGunnar Mills 
183369f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
183469f35306SGunnar Mills     {
183569f35306SGunnar Mills         autoRebootEnabled = false;
183669f35306SGunnar Mills     }
183769f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
183869f35306SGunnar Mills     {
183969f35306SGunnar Mills         autoRebootEnabled = true;
184069f35306SGunnar Mills     }
184169f35306SGunnar Mills     else
184269f35306SGunnar Mills     {
18430fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
184469f35306SGunnar Mills                          << automaticRetryConfig;
184569f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
184669f35306SGunnar Mills                                          "AutomaticRetryConfig");
184769f35306SGunnar Mills         return;
184869f35306SGunnar Mills     }
184969f35306SGunnar Mills 
185069f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
18515e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
185269f35306SGunnar Mills         if (ec)
185369f35306SGunnar Mills         {
185469f35306SGunnar Mills             messages::internalError(aResp->res);
185569f35306SGunnar Mills             return;
185669f35306SGunnar Mills         }
185769f35306SGunnar Mills         },
185869f35306SGunnar Mills         "xyz.openbmc_project.Settings",
185969f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
186069f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
186169f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1862168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
186369f35306SGunnar Mills }
186469f35306SGunnar Mills 
186569f35306SGunnar Mills /**
1866c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1867c6a620f2SGeorge Liu  *
1868c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1869c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1870c6a620f2SGeorge Liu  *
1871c6a620f2SGeorge Liu  * @return None.
1872c6a620f2SGeorge Liu  */
18738d1b46d7Szhanghch05 inline void
18748d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18754e69c904SGunnar Mills                           const std::string& policy)
1876c6a620f2SGeorge Liu {
1877c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1878c6a620f2SGeorge Liu 
1879c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
18800fda0f12SGeorge Liu         {"AlwaysOn",
18810fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
18820fda0f12SGeorge Liu         {"AlwaysOff",
18830fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
18840fda0f12SGeorge Liu         {"LastState",
18850fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1886c6a620f2SGeorge Liu 
1887c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1888c6a620f2SGeorge Liu 
18894e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1890c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1891c6a620f2SGeorge Liu     {
18924e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
18934e69c904SGunnar Mills                                          "PowerRestorePolicy");
1894c6a620f2SGeorge Liu         return;
1895c6a620f2SGeorge Liu     }
1896c6a620f2SGeorge Liu 
1897c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1898c6a620f2SGeorge Liu 
1899c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
19005e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1901c6a620f2SGeorge Liu         if (ec)
1902c6a620f2SGeorge Liu         {
1903c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1904c6a620f2SGeorge Liu             return;
1905c6a620f2SGeorge Liu         }
1906c6a620f2SGeorge Liu         },
1907c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1908c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1909c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1910c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1911168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1912c6a620f2SGeorge Liu }
1913c6a620f2SGeorge Liu 
1914a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1915a6349918SAppaRao Puli /**
1916a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1917a6349918SAppaRao Puli  *
1918a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1919a6349918SAppaRao Puli  *
1920a6349918SAppaRao Puli  * @return None.
1921a6349918SAppaRao Puli  */
19228d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1923a6349918SAppaRao Puli {
1924a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1925bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1926bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1927bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
19285e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
1929b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1930b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1931b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
193250626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
193350626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
193450626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
193550626f4fSJames Feist 
1936a6349918SAppaRao Puli         if (ec)
1937a6349918SAppaRao Puli         {
1938a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1939b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1940b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1941a6349918SAppaRao Puli             return;
1942a6349918SAppaRao Puli         }
1943a6349918SAppaRao Puli 
1944a6349918SAppaRao Puli         const bool* provState = nullptr;
1945a6349918SAppaRao Puli         const bool* lockState = nullptr;
1946bc1d29deSKrzysztof Grobelny 
1947bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
19480d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
19490d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1950bc1d29deSKrzysztof Grobelny 
1951bc1d29deSKrzysztof Grobelny         if (!success)
1952a6349918SAppaRao Puli         {
1953bc1d29deSKrzysztof Grobelny             messages::internalError(aResp->res);
1954bc1d29deSKrzysztof Grobelny             return;
1955a6349918SAppaRao Puli         }
1956a6349918SAppaRao Puli 
1957a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1958a6349918SAppaRao Puli         {
1959a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1960a6349918SAppaRao Puli             messages::internalError(aResp->res);
1961a6349918SAppaRao Puli             return;
1962a6349918SAppaRao Puli         }
1963a6349918SAppaRao Puli 
1964a6349918SAppaRao Puli         if (*provState == true)
1965a6349918SAppaRao Puli         {
1966a6349918SAppaRao Puli             if (*lockState == true)
1967a6349918SAppaRao Puli             {
1968a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1969a6349918SAppaRao Puli             }
1970a6349918SAppaRao Puli             else
1971a6349918SAppaRao Puli             {
1972a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1973a6349918SAppaRao Puli             }
1974a6349918SAppaRao Puli         }
1975a6349918SAppaRao Puli         else
1976a6349918SAppaRao Puli         {
1977a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1978a6349918SAppaRao Puli         }
1979bc1d29deSKrzysztof Grobelny         });
1980a6349918SAppaRao Puli }
1981a6349918SAppaRao Puli #endif
1982a6349918SAppaRao Puli 
1983491d8ee7SSantosh Puranik /**
19843a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
19853a2d0424SChris Cain  *
19863a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19873a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
19883a2d0424SChris Cain  *
19893a2d0424SChris Cain  * @return None.
19903a2d0424SChris Cain  */
19913a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19923a2d0424SChris Cain                                const std::string& modeValue)
19933a2d0424SChris Cain {
19940fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
19953a2d0424SChris Cain     {
19963a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
19973a2d0424SChris Cain     }
19980fda0f12SGeorge Liu     else if (
19990fda0f12SGeorge Liu         modeValue ==
20000fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20013a2d0424SChris Cain     {
20023a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20033a2d0424SChris Cain     }
20040fda0f12SGeorge Liu     else if (modeValue ==
20050fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20063a2d0424SChris Cain     {
20073a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20083a2d0424SChris Cain     }
20090fda0f12SGeorge Liu     else if (modeValue ==
20100fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20113a2d0424SChris Cain     {
20123a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20133a2d0424SChris Cain     }
20143a2d0424SChris Cain     else
20153a2d0424SChris Cain     {
20163a2d0424SChris Cain         // Any other values would be invalid
20173a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20183a2d0424SChris Cain         messages::internalError(aResp->res);
20193a2d0424SChris Cain     }
20203a2d0424SChris Cain }
20213a2d0424SChris Cain 
20223a2d0424SChris Cain /**
20233a2d0424SChris Cain  * @brief Retrieves system power mode
20243a2d0424SChris Cain  *
20253a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20263a2d0424SChris Cain  *
20273a2d0424SChris Cain  * @return None.
20283a2d0424SChris Cain  */
20293a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
20303a2d0424SChris Cain {
20313a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
20323a2d0424SChris Cain 
20333a2d0424SChris Cain     // Get Power Mode object path:
2034e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2035e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2036e99073f5SGeorge Liu     dbus::utility::getSubTree(
2037e99073f5SGeorge Liu         "/", 0, interfaces,
2038e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2039b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
20403a2d0424SChris Cain         if (ec)
20413a2d0424SChris Cain         {
2042002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2043002d39b4SEd Tanous                              << ec;
20443a2d0424SChris Cain             // This is an optional D-Bus object so just return if
20453a2d0424SChris Cain             // error occurs
20463a2d0424SChris Cain             return;
20473a2d0424SChris Cain         }
20483a2d0424SChris Cain         if (subtree.empty())
20493a2d0424SChris Cain         {
20503a2d0424SChris Cain             // As noted above, this is an optional interface so just return
20513a2d0424SChris Cain             // if there is no instance found
20523a2d0424SChris Cain             return;
20533a2d0424SChris Cain         }
20543a2d0424SChris Cain         if (subtree.size() > 1)
20553a2d0424SChris Cain         {
20563a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
20573a2d0424SChris Cain             // error
20583a2d0424SChris Cain             BMCWEB_LOG_DEBUG
20593a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
20603a2d0424SChris Cain                 << subtree.size();
20613a2d0424SChris Cain             messages::internalError(aResp->res);
20623a2d0424SChris Cain             return;
20633a2d0424SChris Cain         }
20643a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
20653a2d0424SChris Cain         {
20663a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
20673a2d0424SChris Cain             messages::internalError(aResp->res);
20683a2d0424SChris Cain             return;
20693a2d0424SChris Cain         }
20703a2d0424SChris Cain         const std::string& path = subtree[0].first;
20713a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
20723a2d0424SChris Cain         if (service.empty())
20733a2d0424SChris Cain         {
20743a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20753a2d0424SChris Cain             messages::internalError(aResp->res);
20763a2d0424SChris Cain             return;
20773a2d0424SChris Cain         }
20783a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
20791e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
20801e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
20811e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
20825e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
20831e1e598dSJonathan Doman                     const std::string& pmode) {
20848a592810SEd Tanous             if (ec2)
20853a2d0424SChris Cain             {
2086002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
20878a592810SEd Tanous                                  << ec2;
20883a2d0424SChris Cain                 messages::internalError(aResp->res);
20893a2d0424SChris Cain                 return;
20903a2d0424SChris Cain             }
20913a2d0424SChris Cain 
2092002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2093002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
20943a2d0424SChris Cain 
20951e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
20961e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
20971e1e598dSJonathan Doman             });
2098e99073f5SGeorge Liu         });
20993a2d0424SChris Cain }
21003a2d0424SChris Cain 
21013a2d0424SChris Cain /**
21023a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21033a2d0424SChris Cain  * name associated with that string
21043a2d0424SChris Cain  *
21053a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21063a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21073a2d0424SChris Cain  *
21083a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21093a2d0424SChris Cain  */
21103a2d0424SChris Cain inline std::string
21113a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21123a2d0424SChris Cain                       const std::string& modeString)
21133a2d0424SChris Cain {
21143a2d0424SChris Cain     std::string mode;
21153a2d0424SChris Cain 
21163a2d0424SChris Cain     if (modeString == "Static")
21173a2d0424SChris Cain     {
21183a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21193a2d0424SChris Cain     }
21203a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21213a2d0424SChris Cain     {
21220fda0f12SGeorge Liu         mode =
21230fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21243a2d0424SChris Cain     }
21253a2d0424SChris Cain     else if (modeString == "PowerSaving")
21263a2d0424SChris Cain     {
21273a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21283a2d0424SChris Cain     }
21293a2d0424SChris Cain     else
21303a2d0424SChris Cain     {
21313a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
21323a2d0424SChris Cain     }
21333a2d0424SChris Cain     return mode;
21343a2d0424SChris Cain }
21353a2d0424SChris Cain 
21363a2d0424SChris Cain /**
21373a2d0424SChris Cain  * @brief Sets system power mode.
21383a2d0424SChris Cain  *
21393a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21403a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
21413a2d0424SChris Cain  *
21423a2d0424SChris Cain  * @return None.
21433a2d0424SChris Cain  */
21443a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21453a2d0424SChris Cain                          const std::string& pmode)
21463a2d0424SChris Cain {
21473a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
21483a2d0424SChris Cain 
21493a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
21503a2d0424SChris Cain     if (powerMode.empty())
21513a2d0424SChris Cain     {
21523a2d0424SChris Cain         return;
21533a2d0424SChris Cain     }
21543a2d0424SChris Cain 
21553a2d0424SChris Cain     // Get Power Mode object path:
2156e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2157e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2158e99073f5SGeorge Liu     dbus::utility::getSubTree(
2159e99073f5SGeorge Liu         "/", 0, interfaces,
2160b9d36b47SEd Tanous         [aResp,
2161e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2162b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21633a2d0424SChris Cain         if (ec)
21643a2d0424SChris Cain         {
2165002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2166002d39b4SEd Tanous                              << ec;
21673a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21683a2d0424SChris Cain             messages::internalError(aResp->res);
21693a2d0424SChris Cain             return;
21703a2d0424SChris Cain         }
21713a2d0424SChris Cain         if (subtree.empty())
21723a2d0424SChris Cain         {
21733a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21743a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
21753a2d0424SChris Cain                                        "PowerMode");
21763a2d0424SChris Cain             return;
21773a2d0424SChris Cain         }
21783a2d0424SChris Cain         if (subtree.size() > 1)
21793a2d0424SChris Cain         {
21803a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21813a2d0424SChris Cain             // error
21823a2d0424SChris Cain             BMCWEB_LOG_DEBUG
21833a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
21843a2d0424SChris Cain                 << subtree.size();
21853a2d0424SChris Cain             messages::internalError(aResp->res);
21863a2d0424SChris Cain             return;
21873a2d0424SChris Cain         }
21883a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21893a2d0424SChris Cain         {
21903a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21913a2d0424SChris Cain             messages::internalError(aResp->res);
21923a2d0424SChris Cain             return;
21933a2d0424SChris Cain         }
21943a2d0424SChris Cain         const std::string& path = subtree[0].first;
21953a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21963a2d0424SChris Cain         if (service.empty())
21973a2d0424SChris Cain         {
21983a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21993a2d0424SChris Cain             messages::internalError(aResp->res);
22003a2d0424SChris Cain             return;
22013a2d0424SChris Cain         }
22023a2d0424SChris Cain 
22033a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22043a2d0424SChris Cain                          << path;
22053a2d0424SChris Cain 
22063a2d0424SChris Cain         // Set the Power Mode property
22073a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
22085e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
22098a592810SEd Tanous             if (ec2)
22103a2d0424SChris Cain             {
22113a2d0424SChris Cain                 messages::internalError(aResp->res);
22123a2d0424SChris Cain                 return;
22133a2d0424SChris Cain             }
22143a2d0424SChris Cain             },
22153a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
22163a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2217168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
2218e99073f5SGeorge Liu         });
22193a2d0424SChris Cain }
22203a2d0424SChris Cain 
22213a2d0424SChris Cain /**
222251709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
222351709ffdSYong Li  *
222451709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
222551709ffdSYong Li  *
222651709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
222751709ffdSYong Li  * translation cannot be done, returns an empty string.
222851709ffdSYong Li  */
222923a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
223051709ffdSYong Li {
223151709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
223251709ffdSYong Li     {
223351709ffdSYong Li         return "None";
223451709ffdSYong Li     }
22353174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
223651709ffdSYong Li     {
223751709ffdSYong Li         return "ResetSystem";
223851709ffdSYong Li     }
22393174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
224051709ffdSYong Li     {
224151709ffdSYong Li         return "PowerDown";
224251709ffdSYong Li     }
22433174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
224451709ffdSYong Li     {
224551709ffdSYong Li         return "PowerCycle";
224651709ffdSYong Li     }
224751709ffdSYong Li 
224851709ffdSYong Li     return "";
224951709ffdSYong Li }
225051709ffdSYong Li 
225151709ffdSYong Li /**
2252c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2253c45f0082SYong Li  *
2254c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2255c45f0082SYong Li  *
2256c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2257c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2258c45f0082SYong Li  */
2259c45f0082SYong Li 
226023a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2261c45f0082SYong Li {
2262c45f0082SYong Li     if (rfAction == "None")
2263c45f0082SYong Li     {
2264c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2265c45f0082SYong Li     }
22663174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2267c45f0082SYong Li     {
2268c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2269c45f0082SYong Li     }
22703174e4dfSEd Tanous     if (rfAction == "PowerDown")
2271c45f0082SYong Li     {
2272c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2273c45f0082SYong Li     }
22743174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2275c45f0082SYong Li     {
2276c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2277c45f0082SYong Li     }
2278c45f0082SYong Li 
2279c45f0082SYong Li     return "";
2280c45f0082SYong Li }
2281c45f0082SYong Li 
2282c45f0082SYong Li /**
228351709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
228451709ffdSYong Li  *
228551709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
228651709ffdSYong Li  *
228751709ffdSYong Li  * @return None.
228851709ffdSYong Li  */
22898d1b46d7Szhanghch05 inline void
22908d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
229151709ffdSYong Li {
229251709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2293bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2294bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2295bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2296bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
22975e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
2298b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
229951709ffdSYong Li         if (ec)
230051709ffdSYong Li         {
230151709ffdSYong Li             // watchdog service is stopped
230251709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
230351709ffdSYong Li             return;
230451709ffdSYong Li         }
230551709ffdSYong Li 
230651709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
230751709ffdSYong Li 
230851709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
230951709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
231051709ffdSYong Li 
231151709ffdSYong Li         // watchdog service is running/enabled
231251709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
231351709ffdSYong Li 
2314bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2315bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
231651709ffdSYong Li 
2317bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2318bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2319bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2320bc1d29deSKrzysztof Grobelny 
2321bc1d29deSKrzysztof Grobelny         if (!success)
232251709ffdSYong Li         {
232351709ffdSYong Li             messages::internalError(aResp->res);
2324601af5edSChicago Duan             return;
232551709ffdSYong Li         }
232651709ffdSYong Li 
2327bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
232851709ffdSYong Li         {
2329bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
233051709ffdSYong Li         }
233151709ffdSYong Li 
2332bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2333bc1d29deSKrzysztof Grobelny         {
2334bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
233551709ffdSYong Li             if (action.empty())
233651709ffdSYong Li             {
233751709ffdSYong Li                 messages::internalError(aResp->res);
2338601af5edSChicago Duan                 return;
233951709ffdSYong Li             }
234051709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
234151709ffdSYong Li         }
2342bc1d29deSKrzysztof Grobelny         });
234351709ffdSYong Li }
234451709ffdSYong Li 
234551709ffdSYong Li /**
2346c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2347c45f0082SYong Li  *
2348c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2349c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2350c45f0082SYong Li  *                       RF request.
2351c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2352c45f0082SYong Li  *
2353c45f0082SYong Li  * @return None.
2354c45f0082SYong Li  */
23558d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2356c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2357c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2358c45f0082SYong Li {
2359c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2360c45f0082SYong Li 
2361c45f0082SYong Li     if (wdtTimeOutAction)
2362c45f0082SYong Li     {
2363c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2364c45f0082SYong Li         // check if TimeOut Action is Valid
2365c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2366c45f0082SYong Li         {
2367c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2368c45f0082SYong Li                              << *wdtTimeOutAction;
2369c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2370c45f0082SYong Li                                              "TimeoutAction");
2371c45f0082SYong Li             return;
2372c45f0082SYong Li         }
2373c45f0082SYong Li 
2374c45f0082SYong Li         crow::connections::systemBus->async_method_call(
23755e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2376c45f0082SYong Li             if (ec)
2377c45f0082SYong Li             {
2378c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2379c45f0082SYong Li                 messages::internalError(aResp->res);
2380c45f0082SYong Li                 return;
2381c45f0082SYong Li             }
2382c45f0082SYong Li             },
2383c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2384c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2385c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2386c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2387168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2388c45f0082SYong Li     }
2389c45f0082SYong Li 
2390c45f0082SYong Li     if (wdtEnable)
2391c45f0082SYong Li     {
2392c45f0082SYong Li         crow::connections::systemBus->async_method_call(
23935e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2394c45f0082SYong Li             if (ec)
2395c45f0082SYong Li             {
2396c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2397c45f0082SYong Li                 messages::internalError(aResp->res);
2398c45f0082SYong Li                 return;
2399c45f0082SYong Li             }
2400c45f0082SYong Li             },
2401c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2402c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2403c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2404c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2405168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2406c45f0082SYong Li     }
2407c45f0082SYong Li }
2408c45f0082SYong Li 
240937bbf98cSChris Cain /**
241037bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
241137bbf98cSChris Cain  *
241237bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
241337bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
241437bbf98cSChris Cain  *
241537bbf98cSChris Cain  * @return true if successful
241637bbf98cSChris Cain  */
24171e5b7c88SJiaqing Zhao inline bool
24181e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
24191e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
242037bbf98cSChris Cain {
2421bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2422bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2423bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2424bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2425bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2426bc1d29deSKrzysztof Grobelny 
2427bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2428bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
24292661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
24302661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
24312661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2432bc1d29deSKrzysztof Grobelny 
2433bc1d29deSKrzysztof Grobelny     if (!success)
243437bbf98cSChris Cain     {
243537bbf98cSChris Cain         return false;
243637bbf98cSChris Cain     }
2437bc1d29deSKrzysztof Grobelny 
2438bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
243937bbf98cSChris Cain     {
2440bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
244137bbf98cSChris Cain     }
2442bc1d29deSKrzysztof Grobelny 
2443bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
244437bbf98cSChris Cain     {
2445bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2446bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
244737bbf98cSChris Cain     }
2448bc1d29deSKrzysztof Grobelny 
2449bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2450bc1d29deSKrzysztof Grobelny     {
2451bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
245237bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
245337bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
245437bbf98cSChris Cain                 .count();
245537bbf98cSChris Cain     }
2456bc1d29deSKrzysztof Grobelny 
2457bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
245837bbf98cSChris Cain     {
2459bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2460bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
246137bbf98cSChris Cain     }
2462bc1d29deSKrzysztof Grobelny 
2463bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
246437bbf98cSChris Cain     {
2465bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
246637bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
246737bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
246837bbf98cSChris Cain                 .count();
246937bbf98cSChris Cain     }
247037bbf98cSChris Cain 
247137bbf98cSChris Cain     return true;
247237bbf98cSChris Cain }
247337bbf98cSChris Cain 
247437bbf98cSChris Cain /**
247537bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
247637bbf98cSChris Cain  *
247737bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
247837bbf98cSChris Cain  *
247937bbf98cSChris Cain  * @return None.
248037bbf98cSChris Cain  */
248137bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
248237bbf98cSChris Cain {
248337bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
248437bbf98cSChris Cain 
248537bbf98cSChris Cain     // Get IdlePowerSaver object path:
2486e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2487e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2488e99073f5SGeorge Liu     dbus::utility::getSubTree(
2489e99073f5SGeorge Liu         "/", 0, interfaces,
2490e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2491b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
249237bbf98cSChris Cain         if (ec)
249337bbf98cSChris Cain         {
249437bbf98cSChris Cain             BMCWEB_LOG_DEBUG
249537bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
249637bbf98cSChris Cain                 << ec;
249737bbf98cSChris Cain             messages::internalError(aResp->res);
249837bbf98cSChris Cain             return;
249937bbf98cSChris Cain         }
250037bbf98cSChris Cain         if (subtree.empty())
250137bbf98cSChris Cain         {
250237bbf98cSChris Cain             // This is an optional interface so just return
250337bbf98cSChris Cain             // if there is no instance found
250437bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
250537bbf98cSChris Cain             return;
250637bbf98cSChris Cain         }
250737bbf98cSChris Cain         if (subtree.size() > 1)
250837bbf98cSChris Cain         {
250937bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
251037bbf98cSChris Cain             // is an error
251137bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
251237bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
251337bbf98cSChris Cain                              << subtree.size();
251437bbf98cSChris Cain             messages::internalError(aResp->res);
251537bbf98cSChris Cain             return;
251637bbf98cSChris Cain         }
251737bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
251837bbf98cSChris Cain         {
251937bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
252037bbf98cSChris Cain             messages::internalError(aResp->res);
252137bbf98cSChris Cain             return;
252237bbf98cSChris Cain         }
252337bbf98cSChris Cain         const std::string& path = subtree[0].first;
252437bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
252537bbf98cSChris Cain         if (service.empty())
252637bbf98cSChris Cain         {
2527002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
252837bbf98cSChris Cain             messages::internalError(aResp->res);
252937bbf98cSChris Cain             return;
253037bbf98cSChris Cain         }
253137bbf98cSChris Cain 
253237bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2533bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2534bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2535bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
25365e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
25371e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
25388a592810SEd Tanous             if (ec2)
253937bbf98cSChris Cain             {
254037bbf98cSChris Cain                 BMCWEB_LOG_ERROR
25418a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
254237bbf98cSChris Cain                 messages::internalError(aResp->res);
254337bbf98cSChris Cain                 return;
254437bbf98cSChris Cain             }
254537bbf98cSChris Cain 
2546e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
254737bbf98cSChris Cain             {
254837bbf98cSChris Cain                 messages::internalError(aResp->res);
254937bbf98cSChris Cain                 return;
255037bbf98cSChris Cain             }
2551bc1d29deSKrzysztof Grobelny             });
2552e99073f5SGeorge Liu         });
255337bbf98cSChris Cain 
255437bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
255537bbf98cSChris Cain }
255637bbf98cSChris Cain 
255737bbf98cSChris Cain /**
255837bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
255937bbf98cSChris Cain  *
256037bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
256137bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
256237bbf98cSChris Cain  *                       RF request.
256337bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
256437bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
256537bbf98cSChris Cain  * before entering idle state.
256637bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
256737bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
256837bbf98cSChris Cain  * before exiting idle state
256937bbf98cSChris Cain  *
257037bbf98cSChris Cain  * @return None.
257137bbf98cSChris Cain  */
257237bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
257337bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
257437bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
257537bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
257637bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
257737bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
257837bbf98cSChris Cain {
257937bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
258037bbf98cSChris Cain 
258137bbf98cSChris Cain     // Get IdlePowerSaver object path:
2582e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2583e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2584e99073f5SGeorge Liu     dbus::utility::getSubTree(
2585e99073f5SGeorge Liu         "/", 0, interfaces,
258637bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2587e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2588b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
258937bbf98cSChris Cain         if (ec)
259037bbf98cSChris Cain         {
259137bbf98cSChris Cain             BMCWEB_LOG_DEBUG
259237bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
259337bbf98cSChris Cain                 << ec;
259437bbf98cSChris Cain             messages::internalError(aResp->res);
259537bbf98cSChris Cain             return;
259637bbf98cSChris Cain         }
259737bbf98cSChris Cain         if (subtree.empty())
259837bbf98cSChris Cain         {
259937bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
260037bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
260137bbf98cSChris Cain                                        "IdlePowerSaver");
260237bbf98cSChris Cain             return;
260337bbf98cSChris Cain         }
260437bbf98cSChris Cain         if (subtree.size() > 1)
260537bbf98cSChris Cain         {
260637bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
260737bbf98cSChris Cain             // is an error
26080fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
26090fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
261037bbf98cSChris Cain                 << subtree.size();
261137bbf98cSChris Cain             messages::internalError(aResp->res);
261237bbf98cSChris Cain             return;
261337bbf98cSChris Cain         }
261437bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
261537bbf98cSChris Cain         {
261637bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
261737bbf98cSChris Cain             messages::internalError(aResp->res);
261837bbf98cSChris Cain             return;
261937bbf98cSChris Cain         }
262037bbf98cSChris Cain         const std::string& path = subtree[0].first;
262137bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
262237bbf98cSChris Cain         if (service.empty())
262337bbf98cSChris Cain         {
2624002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
262537bbf98cSChris Cain             messages::internalError(aResp->res);
262637bbf98cSChris Cain             return;
262737bbf98cSChris Cain         }
262837bbf98cSChris Cain 
262937bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
263037bbf98cSChris Cain         // need to be updated
263137bbf98cSChris Cain 
263237bbf98cSChris Cain         if (ipsEnable)
263337bbf98cSChris Cain         {
263437bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26355e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26368a592810SEd Tanous                 if (ec2)
263737bbf98cSChris Cain                 {
26388a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
263937bbf98cSChris Cain                     messages::internalError(aResp->res);
264037bbf98cSChris Cain                     return;
264137bbf98cSChris Cain                 }
264237bbf98cSChris Cain                 },
264337bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2644002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2645002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
264637bbf98cSChris Cain         }
264737bbf98cSChris Cain         if (ipsEnterUtil)
264837bbf98cSChris Cain         {
264937bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26505e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26518a592810SEd Tanous                 if (ec2)
265237bbf98cSChris Cain                 {
26538a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
265437bbf98cSChris Cain                     messages::internalError(aResp->res);
265537bbf98cSChris Cain                     return;
265637bbf98cSChris Cain                 }
265737bbf98cSChris Cain                 },
265837bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
265937bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
266037bbf98cSChris Cain                 "EnterUtilizationPercent",
2661168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
266237bbf98cSChris Cain         }
266337bbf98cSChris Cain         if (ipsEnterTime)
266437bbf98cSChris Cain         {
266537bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
266637bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
266737bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26685e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26698a592810SEd Tanous                 if (ec2)
267037bbf98cSChris Cain                 {
26718a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
267237bbf98cSChris Cain                     messages::internalError(aResp->res);
267337bbf98cSChris Cain                     return;
267437bbf98cSChris Cain                 }
267537bbf98cSChris Cain                 },
267637bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
267737bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2678168e20c1SEd Tanous                 "EnterDwellTime",
2679168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
268037bbf98cSChris Cain         }
268137bbf98cSChris Cain         if (ipsExitUtil)
268237bbf98cSChris Cain         {
268337bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26845e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26858a592810SEd Tanous                 if (ec2)
268637bbf98cSChris Cain                 {
26878a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
268837bbf98cSChris Cain                     messages::internalError(aResp->res);
268937bbf98cSChris Cain                     return;
269037bbf98cSChris Cain                 }
269137bbf98cSChris Cain                 },
269237bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
269337bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
269437bbf98cSChris Cain                 "ExitUtilizationPercent",
2695168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
269637bbf98cSChris Cain         }
269737bbf98cSChris Cain         if (ipsExitTime)
269837bbf98cSChris Cain         {
269937bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
270037bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
270137bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
27025e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
27038a592810SEd Tanous                 if (ec2)
270437bbf98cSChris Cain                 {
27058a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
270637bbf98cSChris Cain                     messages::internalError(aResp->res);
270737bbf98cSChris Cain                     return;
270837bbf98cSChris Cain                 }
270937bbf98cSChris Cain                 },
271037bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
271137bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2712168e20c1SEd Tanous                 "ExitDwellTime",
2713168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
271437bbf98cSChris Cain         }
2715e99073f5SGeorge Liu         });
271637bbf98cSChris Cain 
271737bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
271837bbf98cSChris Cain }
271937bbf98cSChris Cain 
2720dd60b9edSEd Tanous inline void handleComputerSystemHead(
2721dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2722dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2723dd60b9edSEd Tanous {
2724dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2725dd60b9edSEd Tanous     {
2726dd60b9edSEd Tanous         return;
2727dd60b9edSEd Tanous     }
2728dd60b9edSEd Tanous     asyncResp->res.addHeader(
2729dd60b9edSEd Tanous         boost::beast::http::field::link,
2730dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2731dd60b9edSEd Tanous }
2732dd60b9edSEd Tanous 
2733c45f0082SYong Li /**
2734c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2735c5b2abe0SLewanczyk, Dawid  * Schema
2736c5b2abe0SLewanczyk, Dawid  */
27377e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
27381abe55efSEd Tanous {
27397e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2740dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2741dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2742dd60b9edSEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
2743dd60b9edSEd Tanous 
2744dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2745ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
27467e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2747f4c99e70SEd Tanous             [&app](const crow::Request& req,
27487e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27493ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2750f4c99e70SEd Tanous         {
2751f4c99e70SEd Tanous             return;
2752f4c99e70SEd Tanous         }
2753dd60b9edSEd Tanous 
2754dd60b9edSEd Tanous         asyncResp->res.addHeader(
2755dd60b9edSEd Tanous             boost::beast::http::field::link,
2756dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
27578d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
27580f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
27598d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
27608d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2761462023adSSunitha Harish 
27621e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2763002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
27641e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2765002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
27665e7e2dc5SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27671e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2768002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
27692c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2770002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
27711476687dSEd Tanous 
27721476687dSEd Tanous             nlohmann::json::object_t system;
27731476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
2774b2ba3072SPatrick Williams             ifaceArray.emplace_back(std::move(system));
277594bda602STim Lee             count = ifaceArray.size();
27768a592810SEd Tanous             if (!ec2)
2777462023adSSunitha Harish             {
2778462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
27791476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2780002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2781b2ba3072SPatrick Williams                 ifaceArray.emplace_back(std::move(hypervisor));
27822c70f800SEd Tanous                 count = ifaceArray.size();
2783cb13a392SEd Tanous             }
27841e1e598dSJonathan Doman             });
27857e860f15SJohn Edward Broadbent         });
2786c5b2abe0SLewanczyk, Dawid }
27877e860f15SJohn Edward Broadbent 
27887e860f15SJohn Edward Broadbent /**
27897e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
27907e860f15SJohn Edward Broadbent  */
27914f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27927e860f15SJohn Edward Broadbent {
279389492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
279489492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
279589492a15SPatrick Williams     constexpr const char* interfaceName =
27967e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
279789492a15SPatrick Williams     constexpr const char* method = "NMI";
27987e860f15SJohn Edward Broadbent 
27997e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28005e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28017e860f15SJohn Edward Broadbent         if (ec)
28027e860f15SJohn Edward Broadbent         {
28037e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
28047e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
28057e860f15SJohn Edward Broadbent             return;
28067e860f15SJohn Edward Broadbent         }
28077e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
28087e860f15SJohn Edward Broadbent         },
28097e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28107e860f15SJohn Edward Broadbent }
2811c5b2abe0SLewanczyk, Dawid 
2812c5b2abe0SLewanczyk, Dawid /**
2813cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2814cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2815cc340dd9SEd Tanous  */
28167e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2817cc340dd9SEd Tanous {
2818cc340dd9SEd Tanous     /**
2819cc340dd9SEd Tanous      * Function handles POST method request.
2820cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2821cc340dd9SEd Tanous      */
28227e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
28237e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2824ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2825002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2826002d39b4SEd Tanous             [&app](const crow::Request& req,
28277e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28283ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
282945ca1b86SEd Tanous         {
283045ca1b86SEd Tanous             return;
283145ca1b86SEd Tanous         }
28329712f8acSEd Tanous         std::string resetType;
283315ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
28347e860f15SJohn Edward Broadbent                                        resetType))
2835cc340dd9SEd Tanous         {
2836cc340dd9SEd Tanous             return;
2837cc340dd9SEd Tanous         }
2838cc340dd9SEd Tanous 
2839d22c8396SJason M. Bills         // Get the command and host vs. chassis
2840cc340dd9SEd Tanous         std::string command;
2841543f4400SEd Tanous         bool hostCommand = true;
2842d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2843cc340dd9SEd Tanous         {
2844cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2845d22c8396SJason M. Bills             hostCommand = true;
2846d22c8396SJason M. Bills         }
2847d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2848d22c8396SJason M. Bills         {
2849d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2850d22c8396SJason M. Bills             hostCommand = false;
2851d22c8396SJason M. Bills         }
2852d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2853d22c8396SJason M. Bills         {
285486a0851aSJason M. Bills             command =
285586a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
285686a0851aSJason M. Bills             hostCommand = true;
2857cc340dd9SEd Tanous         }
28589712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2859cc340dd9SEd Tanous         {
2860cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2861d22c8396SJason M. Bills             hostCommand = true;
2862cc340dd9SEd Tanous         }
28639712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2864cc340dd9SEd Tanous         {
28650fda0f12SGeorge Liu             command =
28660fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2867d22c8396SJason M. Bills             hostCommand = true;
2868d22c8396SJason M. Bills         }
2869d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2870d22c8396SJason M. Bills         {
287186a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
287286a0851aSJason M. Bills             hostCommand = true;
2873cc340dd9SEd Tanous         }
2874bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2875bfd5b826SLakshminarayana R. Kammath         {
2876bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2877bfd5b826SLakshminarayana R. Kammath             return;
2878bfd5b826SLakshminarayana R. Kammath         }
2879cc340dd9SEd Tanous         else
2880cc340dd9SEd Tanous         {
28818d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
28828d1b46d7Szhanghch05                                              resetType);
2883cc340dd9SEd Tanous             return;
2884cc340dd9SEd Tanous         }
2885cc340dd9SEd Tanous 
2886d22c8396SJason M. Bills         if (hostCommand)
2887d22c8396SJason M. Bills         {
2888cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
28895e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2890cc340dd9SEd Tanous                 if (ec)
2891cc340dd9SEd Tanous                 {
2892cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2893002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2894d22c8396SJason M. Bills                     {
2895d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2896d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2897d22c8396SJason M. Bills                     }
2898d22c8396SJason M. Bills                     else
2899d22c8396SJason M. Bills                     {
2900f12894f8SJason M. Bills                         messages::internalError(asyncResp->res);
2901d22c8396SJason M. Bills                     }
2902cc340dd9SEd Tanous                     return;
2903cc340dd9SEd Tanous                 }
2904f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2905cc340dd9SEd Tanous                 },
2906cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2907cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2908cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
29099712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2910168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2911cc340dd9SEd Tanous         }
2912d22c8396SJason M. Bills         else
2913d22c8396SJason M. Bills         {
2914d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
29155e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2916d22c8396SJason M. Bills                 if (ec)
2917d22c8396SJason M. Bills                 {
2918d22c8396SJason M. Bills                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2919002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2920d22c8396SJason M. Bills                     {
2921d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2922d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2923d22c8396SJason M. Bills                     }
2924d22c8396SJason M. Bills                     else
2925d22c8396SJason M. Bills                     {
2926d22c8396SJason M. Bills                         messages::internalError(asyncResp->res);
2927d22c8396SJason M. Bills                     }
2928d22c8396SJason M. Bills                     return;
2929d22c8396SJason M. Bills                 }
2930d22c8396SJason M. Bills                 messages::success(asyncResp->res);
2931d22c8396SJason M. Bills                 },
2932d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
2933d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
2934d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
2935002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2936168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2937d22c8396SJason M. Bills         }
29387e860f15SJohn Edward Broadbent         });
2939d22c8396SJason M. Bills }
2940cc340dd9SEd Tanous 
294138c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead(
2942dd60b9edSEd Tanous     App& app, const crow::Request& req,
2943dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2944dd60b9edSEd Tanous {
2945dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2946dd60b9edSEd Tanous     {
2947dd60b9edSEd Tanous         return;
2948dd60b9edSEd Tanous     }
2949dd60b9edSEd Tanous 
2950dd60b9edSEd Tanous     asyncResp->res.addHeader(
2951dd60b9edSEd Tanous         boost::beast::http::field::link,
2952dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2953dd60b9edSEd Tanous }
2954dd60b9edSEd Tanous 
29555c3e9272SAbhishek Patel inline void afterPortRequest(
29565c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29575c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29585c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29595c3e9272SAbhishek Patel {
29605c3e9272SAbhishek Patel     if (ec)
29615c3e9272SAbhishek Patel     {
29625c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29635c3e9272SAbhishek Patel         return;
29645c3e9272SAbhishek Patel     }
29655c3e9272SAbhishek Patel     for (const auto& data : socketData)
29665c3e9272SAbhishek Patel     {
29675c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29685c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29695c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29705c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29715c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29725c3e9272SAbhishek Patel         // need to retrieve port number for
29735c3e9272SAbhishek Patel         // obmc-console-ssh service
29745c3e9272SAbhishek Patel         if (protocolName == "SSH")
29755c3e9272SAbhishek Patel         {
29765c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
29775c3e9272SAbhishek Patel                                           const boost::system::error_code ec1,
29785c3e9272SAbhishek Patel                                           int portNumber) {
29795c3e9272SAbhishek Patel                 if (ec1)
29805c3e9272SAbhishek Patel                 {
29815c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
29825c3e9272SAbhishek Patel                     return;
29835c3e9272SAbhishek Patel                 }
29845c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
29855c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
29865c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
29875c3e9272SAbhishek Patel             });
29885c3e9272SAbhishek Patel         }
29895c3e9272SAbhishek Patel     }
29905c3e9272SAbhishek Patel }
2991cc340dd9SEd Tanous /**
29926617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2993c5b2abe0SLewanczyk, Dawid  */
29947e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
29951abe55efSEd Tanous {
2996dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2997dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystem)
2998dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2999dd60b9edSEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3000c5b2abe0SLewanczyk, Dawid     /**
3001c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
3002c5b2abe0SLewanczyk, Dawid      */
300322d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3004ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3005002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
3006002d39b4SEd Tanous             [&app](const crow::Request& req,
300722d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
300822d268cbSEd Tanous                    const std::string& systemName) {
30093ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
301045ca1b86SEd Tanous         {
301145ca1b86SEd Tanous             return;
301245ca1b86SEd Tanous         }
3013746b56f3SAsmitha Karunanithi 
3014746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3015746b56f3SAsmitha Karunanithi         {
3016746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
3017746b56f3SAsmitha Karunanithi             return;
3018746b56f3SAsmitha Karunanithi         }
3019746b56f3SAsmitha Karunanithi 
302022d268cbSEd Tanous         if (systemName != "system")
302122d268cbSEd Tanous         {
302222d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
302322d268cbSEd Tanous                                        systemName);
302422d268cbSEd Tanous             return;
302522d268cbSEd Tanous         }
3026dd60b9edSEd Tanous         asyncResp->res.addHeader(
3027dd60b9edSEd Tanous             boost::beast::http::field::link,
3028dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30298d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
303037bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
30318d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
30328d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
30338d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
30348d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
30358d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
30368d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
30378d1b46d7Szhanghch05             "Disabled";
30388d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
30398d1b46d7Szhanghch05             uint64_t(0);
30408d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
30418d1b46d7Szhanghch05             "Disabled";
3042002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
304304a258f4SEd Tanous 
30441476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
30451476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
30461476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
30471476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
30481476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
30491476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
30503179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
30513179105bSSunny Srivastava             "/redfish/v1/Systems/system/FabricAdapters";
3052029573d4SEd Tanous 
3053002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
30541476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
30551476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
30561476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
30571476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
3058c5b2abe0SLewanczyk, Dawid 
30591476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
30601476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
30611476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
30621476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
3063c4bf6374SJason M. Bills 
30641476687dSEd Tanous         nlohmann::json::array_t managedBy;
30651476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
30661476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3067002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
30681476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
30691476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
30700e8ac5e7SGunnar Mills 
30710e8ac5e7SGunnar Mills         // Fill in SerialConsole info
3072002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3073002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3074002d39b4SEd Tanous             true;
30751476687dSEd Tanous 
30760e8ac5e7SGunnar Mills         // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
30771476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
30781476687dSEd Tanous             true;
30791476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
30801476687dSEd Tanous         asyncResp->res
30811476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
30821476687dSEd Tanous             "Press ~. to exit console";
30835c3e9272SAbhishek Patel         getPortStatusAndPath(std::span{protocolToDBusForSystems},
30845c3e9272SAbhishek Patel                              std::bind_front(afterPortRequest, asyncResp));
30850e8ac5e7SGunnar Mills 
30860e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
30870e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3088002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3089002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3090002d39b4SEd Tanous             4;
3091613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3092613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
30931476687dSEd Tanous 
30940e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
30957a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3096b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
30972ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3098e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3099e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3100b49ac873SJames Feist 
3101b49ac873SJames Feist         auto health = std::make_shared<HealthPopulate>(asyncResp);
31027a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
31037a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
31047a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3105914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3106b49ac873SJames Feist             if (ec)
3107b49ac873SJames Feist             {
3108b49ac873SJames Feist                 // no inventory
3109b49ac873SJames Feist                 return;
3110b49ac873SJames Feist             }
3111b49ac873SJames Feist 
3112914e2d5dSEd Tanous             health->inventory = resp;
31137a1dbc48SGeorge Liu             });
3114b49ac873SJames Feist 
3115b49ac873SJames Feist         health->populate();
3116b49ac873SJames Feist 
3117002d39b4SEd Tanous         getMainChassisId(asyncResp,
3118002d39b4SEd Tanous                          [](const std::string& chassisId,
31198d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3120b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3121b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3122*ef4c65b7SEd Tanous             chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3123*ef4c65b7SEd Tanous                                                        chassisId);
3124002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3125c5d03ff4SJennifer Lee         });
3126a3002228SAppaRao Puli 
31279f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
31289f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3129a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
31305bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
31316c34de48SEd Tanous         getHostState(asyncResp);
3132491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
3133978b8803SAndrew Geissler         getBootProgress(asyncResp);
3134b6d5d45cSHieu Huynh         getBootProgressLastStateTime(asyncResp);
3135adbe192aSJason M. Bills         getPCIeDeviceList(asyncResp, "PCIeDevices");
313651709ffdSYong Li         getHostWatchdogTimer(asyncResp);
3137c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
3138797d5daeSCorey Hardesty         getAutomaticRetryPolicy(asyncResp);
3139c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
3140a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3141a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
3142a6349918SAppaRao Puli #endif
31431981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
31443a2d0424SChris Cain         getPowerMode(asyncResp);
314537bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
31467e860f15SJohn Edward Broadbent         });
3147550a6bf8SJiaqing Zhao 
314822d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3149ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
31507e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
315145ca1b86SEd Tanous             [&app](const crow::Request& req,
315222d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
315322d268cbSEd Tanous                    const std::string& systemName) {
31543ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
315545ca1b86SEd Tanous         {
315645ca1b86SEd Tanous             return;
315745ca1b86SEd Tanous         }
315822d268cbSEd Tanous         if (systemName != "system")
315922d268cbSEd Tanous         {
316022d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
316122d268cbSEd Tanous                                        systemName);
316222d268cbSEd Tanous             return;
316322d268cbSEd Tanous         }
316422d268cbSEd Tanous 
3165dd60b9edSEd Tanous         asyncResp->res.addHeader(
3166dd60b9edSEd Tanous             boost::beast::http::field::link,
3167dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3168dd60b9edSEd Tanous 
31699f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
3170cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
317198e386ecSGunnar Mills         std::optional<std::string> assetTag;
3172c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
31733a2d0424SChris Cain         std::optional<std::string> powerMode;
3174550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
3175550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
3176550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
3177550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
3178550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
3179550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
3180797d5daeSCorey Hardesty         std::optional<uint32_t> bootAutomaticRetryAttempts;
3181550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
3182550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
3183550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
3184550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
3185550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
3186550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
3187550a6bf8SJiaqing Zhao 
3188550a6bf8SJiaqing Zhao         // clang-format off
318915ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3190550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3191550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
31927e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3193550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3194550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3195550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3196550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3197550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3198550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3199550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3200550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3201550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3202797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3203550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3204550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3205550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3206550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3207550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3208550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
32096617338dSEd Tanous                 {
32106617338dSEd Tanous                     return;
32116617338dSEd Tanous                 }
3212550a6bf8SJiaqing Zhao         // clang-format on
3213491d8ee7SSantosh Puranik 
32148d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3215c45f0082SYong Li 
321698e386ecSGunnar Mills         if (assetTag)
321798e386ecSGunnar Mills         {
321898e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
321998e386ecSGunnar Mills         }
322098e386ecSGunnar Mills 
3221550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3222c45f0082SYong Li         {
3223f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3224c45f0082SYong Li         }
3225c45f0082SYong Li 
3226cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
322769f35306SGunnar Mills         {
3228002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3229491d8ee7SSantosh Puranik         }
3230550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
323169f35306SGunnar Mills         {
3232550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
323369f35306SGunnar Mills         }
3234ac7e1e0bSAli Ahmed 
3235797d5daeSCorey Hardesty         if (bootAutomaticRetryAttempts)
3236797d5daeSCorey Hardesty         {
3237797d5daeSCorey Hardesty             setAutomaticRetryAttempts(asyncResp,
3238797d5daeSCorey Hardesty                                       bootAutomaticRetryAttempts.value());
3239797d5daeSCorey Hardesty         }
3240797d5daeSCorey Hardesty 
3241550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3242ac7e1e0bSAli Ahmed         {
3243550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3244550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
324569f35306SGunnar Mills         }
3246265c1602SJohnathan Mantey 
32479f8bfa7cSGunnar Mills         if (locationIndicatorActive)
32489f8bfa7cSGunnar Mills         {
3249002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32509f8bfa7cSGunnar Mills         }
32519f8bfa7cSGunnar Mills 
32527e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
32537e860f15SJohn Edward Broadbent         // passed
32549712f8acSEd Tanous         if (indicatorLed)
32556617338dSEd Tanous         {
3256f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3257002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3258d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3259d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
32606617338dSEd Tanous         }
3261c6a620f2SGeorge Liu 
3262c6a620f2SGeorge Liu         if (powerRestorePolicy)
3263c6a620f2SGeorge Liu         {
32644e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3265c6a620f2SGeorge Liu         }
32663a2d0424SChris Cain 
32673a2d0424SChris Cain         if (powerMode)
32683a2d0424SChris Cain         {
32693a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
32703a2d0424SChris Cain         }
327137bbf98cSChris Cain 
3272550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3273550a6bf8SJiaqing Zhao             ipsExitTime)
327437bbf98cSChris Cain         {
3275002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3276002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
327737bbf98cSChris Cain         }
32787e860f15SJohn Edward Broadbent         });
3279c5b2abe0SLewanczyk, Dawid }
32801cb1a9e6SAppaRao Puli 
328138c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3282dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
3283dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3284dd60b9edSEd Tanous {
3285dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3286dd60b9edSEd Tanous     {
3287dd60b9edSEd Tanous         return;
3288dd60b9edSEd Tanous     }
3289dd60b9edSEd Tanous     asyncResp->res.addHeader(
3290dd60b9edSEd Tanous         boost::beast::http::field::link,
3291dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3292dd60b9edSEd Tanous }
3293dd60b9edSEd Tanous 
32941cb1a9e6SAppaRao Puli /**
32951cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
32961cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
32971cb1a9e6SAppaRao Puli  */
32987e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
32991cb1a9e6SAppaRao Puli {
3300dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3301dd60b9edSEd Tanous         .privileges(redfish::privileges::headActionInfo)
3302dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3303dd60b9edSEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
33041cb1a9e6SAppaRao Puli     /**
33051cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
33061cb1a9e6SAppaRao Puli      */
330722d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3308ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
33097e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
331045ca1b86SEd Tanous             [&app](const crow::Request& req,
331122d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331222d268cbSEd Tanous                    const std::string& systemName) {
33133ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
331445ca1b86SEd Tanous         {
331545ca1b86SEd Tanous             return;
331645ca1b86SEd Tanous         }
3317746b56f3SAsmitha Karunanithi 
3318746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3319746b56f3SAsmitha Karunanithi         {
3320746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3321746b56f3SAsmitha Karunanithi             return;
3322746b56f3SAsmitha Karunanithi         }
3323746b56f3SAsmitha Karunanithi 
332422d268cbSEd Tanous         if (systemName != "system")
332522d268cbSEd Tanous         {
332622d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
332722d268cbSEd Tanous                                        systemName);
332822d268cbSEd Tanous             return;
332922d268cbSEd Tanous         }
333022d268cbSEd Tanous 
3331dd60b9edSEd Tanous         asyncResp->res.addHeader(
3332dd60b9edSEd Tanous             boost::beast::http::field::link,
3333dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
33341476687dSEd Tanous 
33351476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
33361476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
33371476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
33381476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
33391476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
33401476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
33413215e700SNan Zhou 
33423215e700SNan Zhou         nlohmann::json::array_t parameters;
33433215e700SNan Zhou         nlohmann::json::object_t parameter;
33443215e700SNan Zhou 
33453215e700SNan Zhou         parameter["Name"] = "ResetType";
33463215e700SNan Zhou         parameter["Required"] = true;
33473215e700SNan Zhou         parameter["DataType"] = "String";
33483215e700SNan Zhou         nlohmann::json::array_t allowableValues;
33493215e700SNan Zhou         allowableValues.emplace_back("On");
33503215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
33513215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
33523215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
33533215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
33543215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
33553215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
33563215e700SNan Zhou         allowableValues.emplace_back("Nmi");
33573215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
33583215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
33593215e700SNan Zhou 
33603215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
33617e860f15SJohn Edward Broadbent         });
33621cb1a9e6SAppaRao Puli }
3363c5b2abe0SLewanczyk, Dawid } // namespace redfish
3364