xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 5e7e2dc585dc7a7e62d2b648b541e7f50c39ea5d)
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"
221c8fba97SJames Feist #include "led.hpp"
23f5c9f8bdSJason M. Bills #include "pcie.hpp"
24f4c99e70SEd Tanous #include "query.hpp"
25c5d03ff4SJennifer Lee #include "redfish_util.hpp"
263ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
273ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
283ccb3adbSEd Tanous #include "utils/json_utils.hpp"
293ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
302b82937eSEd Tanous #include "utils/time_utils.hpp"
31c5d03ff4SJennifer Lee 
329712f8acSEd Tanous #include <boost/container/flat_map.hpp>
33e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
341e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
35bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
361214b7e7SGunnar Mills 
377a1dbc48SGeorge Liu #include <array>
387a1dbc48SGeorge Liu #include <string_view>
39abf2add6SEd Tanous #include <variant>
40c5b2abe0SLewanczyk, Dawid 
411abe55efSEd Tanous namespace redfish
421abe55efSEd Tanous {
43c5b2abe0SLewanczyk, Dawid 
449d3ae10eSAlpana Kumari /**
459d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
469d3ae10eSAlpana Kumari  *
479d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
489d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
499d3ae10eSAlpana Kumari  *
509d3ae10eSAlpana Kumari  * @return None.
519d3ae10eSAlpana Kumari  */
528d1b46d7Szhanghch05 inline void
538d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
541e1e598dSJonathan Doman                          bool isDimmFunctional)
559d3ae10eSAlpana Kumari {
561e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
579d3ae10eSAlpana Kumari 
589d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
599d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
609d3ae10eSAlpana Kumari     // ENABLED.
6102cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
629d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
639d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
649d3ae10eSAlpana Kumari     {
65e05aec50SEd Tanous         if (isDimmFunctional)
669d3ae10eSAlpana Kumari         {
679d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
689d3ae10eSAlpana Kumari                 "Enabled";
699d3ae10eSAlpana Kumari         }
709d3ae10eSAlpana Kumari     }
719d3ae10eSAlpana Kumari }
729d3ae10eSAlpana Kumari 
7357e8c9beSAlpana Kumari /*
7457e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
7557e8c9beSAlpana Kumari  *
7657e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
7757e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
7857e8c9beSAlpana Kumari  *
7957e8c9beSAlpana Kumari  * @return None.
8057e8c9beSAlpana Kumari  */
811e1e598dSJonathan Doman inline void
821e1e598dSJonathan Doman     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
831e1e598dSJonathan Doman                            bool isCpuPresent)
8457e8c9beSAlpana Kumari {
851e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
8657e8c9beSAlpana Kumari 
8755f79e6fSEd Tanous     if (isCpuPresent)
8857e8c9beSAlpana Kumari     {
89b4b9595aSJames Feist         nlohmann::json& procCount =
90b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
9155f79e6fSEd Tanous         auto* procCountPtr =
92b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
93b4b9595aSJames Feist         if (procCountPtr != nullptr)
94b4b9595aSJames Feist         {
95b4b9595aSJames Feist             // shouldn't be possible to be nullptr
96b4b9595aSJames Feist             *procCountPtr += 1;
9757e8c9beSAlpana Kumari         }
98b4b9595aSJames Feist     }
9957e8c9beSAlpana Kumari }
10057e8c9beSAlpana Kumari 
10157e8c9beSAlpana Kumari /*
10257e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
10357e8c9beSAlpana Kumari  *        CPU Functional State
10457e8c9beSAlpana Kumari  *
10557e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
10657e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
10757e8c9beSAlpana Kumari  *
10857e8c9beSAlpana Kumari  * @return None.
10957e8c9beSAlpana Kumari  */
1101e1e598dSJonathan Doman inline void
1111e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1121e1e598dSJonathan Doman                              bool isCpuFunctional)
11357e8c9beSAlpana Kumari {
1141e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
11557e8c9beSAlpana Kumari 
11602cad96eSEd Tanous     const nlohmann::json& prevProcState =
11757e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
11857e8c9beSAlpana Kumari 
11957e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
12057e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
12157e8c9beSAlpana Kumari     // Functional.
12257e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
12357e8c9beSAlpana Kumari     {
124e05aec50SEd Tanous         if (isCpuFunctional)
12557e8c9beSAlpana Kumari         {
12657e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
12757e8c9beSAlpana Kumari                 "Enabled";
12857e8c9beSAlpana Kumari         }
12957e8c9beSAlpana Kumari     }
13057e8c9beSAlpana Kumari }
13157e8c9beSAlpana Kumari 
132382d6475SAli Ahmed inline void getProcessorProperties(
133382d6475SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
134382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
135382d6475SAli Ahmed         properties)
13603fbed92SAli Ahmed {
13703fbed92SAli Ahmed 
13803fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
13903fbed92SAli Ahmed 
14003fbed92SAli Ahmed     // TODO: Get Model
14103fbed92SAli Ahmed 
142bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
14303fbed92SAli Ahmed 
144bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
145bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
14603fbed92SAli Ahmed 
147bc1d29deSKrzysztof Grobelny     if (!success)
14803fbed92SAli Ahmed     {
14903fbed92SAli Ahmed         messages::internalError(aResp->res);
15003fbed92SAli Ahmed         return;
15103fbed92SAli Ahmed     }
15203fbed92SAli Ahmed 
153bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
15403fbed92SAli Ahmed     {
155bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
156bc1d29deSKrzysztof Grobelny             aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
157bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
158bc1d29deSKrzysztof Grobelny 
159bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
160bc1d29deSKrzysztof Grobelny         {
161bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
16203fbed92SAli Ahmed         }
16303fbed92SAli Ahmed         else
16403fbed92SAli Ahmed         {
165bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
16603fbed92SAli Ahmed         }
16703fbed92SAli Ahmed     }
16803fbed92SAli Ahmed }
16903fbed92SAli Ahmed 
17003fbed92SAli Ahmed /*
17103fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
17203fbed92SAli Ahmed  *
17303fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
17403fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
17503fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
17603fbed92SAli Ahmed  *
17703fbed92SAli Ahmed  * @return None.
17803fbed92SAli Ahmed  */
17903fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18003fbed92SAli Ahmed                                 const std::string& service,
18103fbed92SAli Ahmed                                 const std::string& path)
18203fbed92SAli Ahmed {
18303fbed92SAli Ahmed 
184*5e7e2dc5SEd Tanous     auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3,
185382d6475SAli Ahmed                                        const bool cpuPresenceCheck) {
186382d6475SAli Ahmed         if (ec3)
187382d6475SAli Ahmed         {
188382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
189382d6475SAli Ahmed             return;
190382d6475SAli Ahmed         }
191382d6475SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
192382d6475SAli Ahmed     };
193382d6475SAli Ahmed 
194*5e7e2dc5SEd Tanous     auto getCpuFunctionalState = [aResp](const boost::system::error_code& ec3,
195382d6475SAli Ahmed                                          const bool cpuFunctionalCheck) {
196382d6475SAli Ahmed         if (ec3)
197382d6475SAli Ahmed         {
198382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
199382d6475SAli Ahmed             return;
200382d6475SAli Ahmed         }
201382d6475SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
202382d6475SAli Ahmed     };
203382d6475SAli Ahmed 
204382d6475SAli Ahmed     // Get the Presence of CPU
205382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
206382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
207382d6475SAli Ahmed         "xyz.openbmc_project.Inventory.Item", "Present",
208382d6475SAli Ahmed         std::move(getCpuPresenceState));
209382d6475SAli Ahmed 
210382d6475SAli Ahmed     // Get the Functional State
211382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
212382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
213382d6475SAli Ahmed         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
214382d6475SAli Ahmed         std::move(getCpuFunctionalState));
215382d6475SAli Ahmed 
216bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
217bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
218bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
21903fbed92SAli Ahmed         [aResp, service,
220*5e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
221b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
22203fbed92SAli Ahmed         if (ec2)
22303fbed92SAli Ahmed         {
22403fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
22503fbed92SAli Ahmed             messages::internalError(aResp->res);
22603fbed92SAli Ahmed             return;
22703fbed92SAli Ahmed         }
228382d6475SAli Ahmed         getProcessorProperties(aResp, properties);
229bc1d29deSKrzysztof Grobelny         });
23003fbed92SAli Ahmed }
23103fbed92SAli Ahmed 
23257e8c9beSAlpana Kumari /*
233c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
234c5b2abe0SLewanczyk, Dawid  *
235c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2368f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
237c5b2abe0SLewanczyk, Dawid  *
238c5b2abe0SLewanczyk, Dawid  * @return None.
239c5b2abe0SLewanczyk, Dawid  */
240b5a76932SEd Tanous inline void
2418d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
242b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2431abe55efSEd Tanous {
24455c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
245e99073f5SGeorge Liu     constexpr std::array<std::string_view, 5> interfaces = {
246e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Decorator.Asset",
247e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Cpu",
248e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
249e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System",
250e99073f5SGeorge Liu         "xyz.openbmc_project.Common.UUID",
251e99073f5SGeorge Liu     };
252e99073f5SGeorge Liu     dbus::utility::getSubTree(
253e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
254b9d36b47SEd Tanous         [aResp,
255e99073f5SGeorge Liu          systemHealth](const boost::system::error_code& ec,
256b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
2571abe55efSEd Tanous         if (ec)
2581abe55efSEd Tanous         {
25955c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
260f12894f8SJason M. Bills             messages::internalError(aResp->res);
261c5b2abe0SLewanczyk, Dawid             return;
262c5b2abe0SLewanczyk, Dawid         }
263c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
264002d39b4SEd Tanous         for (const std::pair<
265002d39b4SEd Tanous                  std::string,
266002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
2671214b7e7SGunnar Mills                  object : subtree)
2681abe55efSEd Tanous         {
269c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
27055c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
271002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
2721214b7e7SGunnar Mills                 connectionNames = object.second;
27326f6976fSEd Tanous             if (connectionNames.empty())
2741abe55efSEd Tanous             {
275c5b2abe0SLewanczyk, Dawid                 continue;
276c5b2abe0SLewanczyk, Dawid             }
277029573d4SEd Tanous 
2785bc2dc8eSJames Feist             auto memoryHealth = std::make_shared<HealthPopulate>(
279dfababfcSNan Zhou                 aResp, "/MemorySummary/Status"_json_pointer);
2805bc2dc8eSJames Feist 
2815bc2dc8eSJames Feist             auto cpuHealth = std::make_shared<HealthPopulate>(
282dfababfcSNan Zhou                 aResp, "/ProcessorSummary/Status"_json_pointer);
2835bc2dc8eSJames Feist 
2845bc2dc8eSJames Feist             systemHealth->children.emplace_back(memoryHealth);
2855bc2dc8eSJames Feist             systemHealth->children.emplace_back(cpuHealth);
2865bc2dc8eSJames Feist 
2876c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
2886c34de48SEd Tanous             // BiosVer
28904a258f4SEd Tanous             for (const auto& connection : connectionNames)
2901abe55efSEd Tanous             {
29104a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
2921abe55efSEd Tanous                 {
29304a258f4SEd Tanous                     if (interfaceName ==
29404a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
2951abe55efSEd Tanous                     {
2961abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
29704a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
2989d3ae10eSAlpana Kumari 
299bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
300bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
301bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Inventory.Item.Dimm",
3029d3ae10eSAlpana Kumari                             [aResp, service{connection.first},
303*5e7e2dc5SEd Tanous                              path](const boost::system::error_code& ec2,
304b9d36b47SEd Tanous                                    const dbus::utility::DBusPropertiesMap&
3051214b7e7SGunnar Mills                                        properties) {
306cb13a392SEd Tanous                             if (ec2)
3071abe55efSEd Tanous                             {
308002d39b4SEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error "
309002d39b4SEd Tanous                                                  << ec2;
310f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
311c5b2abe0SLewanczyk, Dawid                                 return;
312c5b2abe0SLewanczyk, Dawid                             }
313002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
314c5b2abe0SLewanczyk, Dawid                                              << " Dimm properties.";
3159d3ae10eSAlpana Kumari 
316bc1d29deSKrzysztof Grobelny                             if (properties.empty())
3179d3ae10eSAlpana Kumari                             {
3181e1e598dSJonathan Doman                                 sdbusplus::asio::getProperty<bool>(
319002d39b4SEd Tanous                                     *crow::connections::systemBus, service,
320002d39b4SEd Tanous                                     path,
3211e1e598dSJonathan Doman                                     "xyz.openbmc_project.State."
3221e1e598dSJonathan Doman                                     "Decorator.OperationalStatus",
3231e1e598dSJonathan Doman                                     "Functional",
324*5e7e2dc5SEd Tanous                                     [aResp](
325*5e7e2dc5SEd Tanous                                         const boost::system::error_code& ec3,
3261e1e598dSJonathan Doman                                         bool dimmState) {
327cb13a392SEd Tanous                                     if (ec3)
3289d3ae10eSAlpana Kumari                                     {
3299d3ae10eSAlpana Kumari                                         BMCWEB_LOG_ERROR
330002d39b4SEd Tanous                                             << "DBUS response error " << ec3;
3319d3ae10eSAlpana Kumari                                         return;
3329d3ae10eSAlpana Kumari                                     }
333002d39b4SEd Tanous                                     updateDimmProperties(aResp, dimmState);
3341e1e598dSJonathan Doman                                     });
335bc1d29deSKrzysztof Grobelny                                 return;
3369d3ae10eSAlpana Kumari                             }
337bc1d29deSKrzysztof Grobelny 
338bc1d29deSKrzysztof Grobelny                             const uint32_t* memorySizeInKB = nullptr;
339bc1d29deSKrzysztof Grobelny 
340bc1d29deSKrzysztof Grobelny                             const bool success =
341bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
342bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
343bc1d29deSKrzysztof Grobelny                                     properties, "MemorySizeInKB",
344bc1d29deSKrzysztof Grobelny                                     memorySizeInKB);
345bc1d29deSKrzysztof Grobelny 
346bc1d29deSKrzysztof Grobelny                             if (!success)
347bc1d29deSKrzysztof Grobelny                             {
348bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
349bc1d29deSKrzysztof Grobelny                                 return;
350bc1d29deSKrzysztof Grobelny                             }
351bc1d29deSKrzysztof Grobelny 
352bc1d29deSKrzysztof Grobelny                             if (memorySizeInKB != nullptr)
353bc1d29deSKrzysztof Grobelny                             {
354bc1d29deSKrzysztof Grobelny                                 nlohmann::json& totalMemory =
355bc1d29deSKrzysztof Grobelny                                     aResp->res
356bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
357bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"];
358bc1d29deSKrzysztof Grobelny                                 const uint64_t* preValue =
359bc1d29deSKrzysztof Grobelny                                     totalMemory.get_ptr<const uint64_t*>();
360bc1d29deSKrzysztof Grobelny                                 if (preValue == nullptr)
361bc1d29deSKrzysztof Grobelny                                 {
362bc1d29deSKrzysztof Grobelny                                     aResp->res
363bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
364bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
365bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024);
366bc1d29deSKrzysztof Grobelny                                 }
367bc1d29deSKrzysztof Grobelny                                 else
368bc1d29deSKrzysztof Grobelny                                 {
369bc1d29deSKrzysztof Grobelny                                     aResp->res
370bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
371bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
372bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024) +
373bc1d29deSKrzysztof Grobelny                                         *preValue;
374bc1d29deSKrzysztof Grobelny                                 }
375bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["MemorySummary"]["Status"]
376bc1d29deSKrzysztof Grobelny                                                     ["State"] = "Enabled";
377bc1d29deSKrzysztof Grobelny                             }
378bc1d29deSKrzysztof Grobelny                             });
3795bc2dc8eSJames Feist 
3805bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
3811abe55efSEd Tanous                     }
38204a258f4SEd Tanous                     else if (interfaceName ==
38304a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
3841abe55efSEd Tanous                     {
3851abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
38604a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
38757e8c9beSAlpana Kumari 
38803fbed92SAli Ahmed                         getProcessorSummary(aResp, connection.first, path);
3895bc2dc8eSJames Feist 
3905bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
3911abe55efSEd Tanous                     }
392002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
3931abe55efSEd Tanous                     {
3941abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
39504a258f4SEd Tanous                             << "Found UUID, now get its properties.";
396bc1d29deSKrzysztof Grobelny 
397bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
398bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
399bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
400*5e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec3,
401b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4021214b7e7SGunnar Mills                                         properties) {
403cb13a392SEd Tanous                             if (ec3)
4041abe55efSEd Tanous                             {
405002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
406002d39b4SEd Tanous                                                  << ec3;
407f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
408c5b2abe0SLewanczyk, Dawid                                 return;
409c5b2abe0SLewanczyk, Dawid                             }
410002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
411c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
41204a258f4SEd Tanous 
413bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
414bc1d29deSKrzysztof Grobelny 
415bc1d29deSKrzysztof Grobelny                             const bool success =
416bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
417bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
418bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
419bc1d29deSKrzysztof Grobelny 
420bc1d29deSKrzysztof Grobelny                             if (!success)
4211abe55efSEd Tanous                             {
422bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
423bc1d29deSKrzysztof Grobelny                                 return;
424bc1d29deSKrzysztof Grobelny                             }
425bc1d29deSKrzysztof Grobelny 
426bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
427bc1d29deSKrzysztof Grobelny                             {
428bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
42904a258f4SEd Tanous                                 if (valueStr.size() == 32)
4301abe55efSEd Tanous                                 {
431029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
432029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
433029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
434029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
43504a258f4SEd Tanous                                 }
436bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
437002d39b4SEd Tanous                                 aResp->res.jsonValue["UUID"] = valueStr;
438c5b2abe0SLewanczyk, Dawid                             }
439bc1d29deSKrzysztof Grobelny                             });
440c5b2abe0SLewanczyk, Dawid                     }
441029573d4SEd Tanous                     else if (interfaceName ==
442029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4431abe55efSEd Tanous                     {
444bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
445bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
446bc1d29deSKrzysztof Grobelny                             path,
447bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
448*5e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
449b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4501214b7e7SGunnar Mills                                         propertiesList) {
451cb13a392SEd Tanous                             if (ec2)
452029573d4SEd Tanous                             {
453e4a4b9a9SJames Feist                                 // doesn't have to include this
454e4a4b9a9SJames Feist                                 // interface
455029573d4SEd Tanous                                 return;
456029573d4SEd Tanous                             }
457002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
458029573d4SEd Tanous                                              << " properties for system";
459bc1d29deSKrzysztof Grobelny 
460bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
461bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
462bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
463bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
464bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
465bc1d29deSKrzysztof Grobelny 
466bc1d29deSKrzysztof Grobelny                             const bool success =
467bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
468bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
469bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
470bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
471bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
472bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
473bc1d29deSKrzysztof Grobelny 
474bc1d29deSKrzysztof Grobelny                             if (!success)
475029573d4SEd Tanous                             {
476bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
477bc1d29deSKrzysztof Grobelny                                 return;
478029573d4SEd Tanous                             }
479bc1d29deSKrzysztof Grobelny 
480bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
481bc1d29deSKrzysztof Grobelny                             {
482bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["PartNumber"] =
483bc1d29deSKrzysztof Grobelny                                     *partNumber;
484029573d4SEd Tanous                             }
485bc1d29deSKrzysztof Grobelny 
486bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
487bc1d29deSKrzysztof Grobelny                             {
488bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SerialNumber"] =
489bc1d29deSKrzysztof Grobelny                                     *serialNumber;
490bc1d29deSKrzysztof Grobelny                             }
491bc1d29deSKrzysztof Grobelny 
492bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
493bc1d29deSKrzysztof Grobelny                             {
494bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Manufacturer"] =
495bc1d29deSKrzysztof Grobelny                                     *manufacturer;
496bc1d29deSKrzysztof Grobelny                             }
497bc1d29deSKrzysztof Grobelny 
498bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
499bc1d29deSKrzysztof Grobelny                             {
500bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Model"] = *model;
501bc1d29deSKrzysztof Grobelny                             }
502bc1d29deSKrzysztof Grobelny 
503bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
504bc1d29deSKrzysztof Grobelny                             {
505bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SubModel"] = *subModel;
506fc5afcf9Sbeccabroek                             }
507c1e236a6SGunnar Mills 
508cb7e1e7bSAndrew Geissler                             // Grab the bios version
509eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
510eee0013eSWilly Tu                                 aResp, sw_util::biosPurpose, "BiosVersion",
511002d39b4SEd Tanous                                 false);
512bc1d29deSKrzysztof Grobelny                             });
513e4a4b9a9SJames Feist 
5141e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5151e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5161e1e598dSJonathan Doman                             path,
5171e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5181e1e598dSJonathan Doman                             "AssetTag",
5191e1e598dSJonathan Doman                             "AssetTag",
520*5e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
5211e1e598dSJonathan Doman                                     const std::string& value) {
522cb13a392SEd Tanous                             if (ec2)
523e4a4b9a9SJames Feist                             {
524e4a4b9a9SJames Feist                                 // doesn't have to include this
525e4a4b9a9SJames Feist                                 // interface
526e4a4b9a9SJames Feist                                 return;
527e4a4b9a9SJames Feist                             }
528e4a4b9a9SJames Feist 
5291e1e598dSJonathan Doman                             aResp->res.jsonValue["AssetTag"] = value;
5301e1e598dSJonathan Doman                             });
531029573d4SEd Tanous                     }
532029573d4SEd Tanous                 }
533bc1d29deSKrzysztof Grobelny                 break;
534029573d4SEd Tanous             }
535c5b2abe0SLewanczyk, Dawid         }
5366617338dSEd Tanous         });
537c5b2abe0SLewanczyk, Dawid }
538c5b2abe0SLewanczyk, Dawid 
539c5b2abe0SLewanczyk, Dawid /**
540c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
541c5b2abe0SLewanczyk, Dawid  *
542c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
543c5b2abe0SLewanczyk, Dawid  *
544c5b2abe0SLewanczyk, Dawid  * @return None.
545c5b2abe0SLewanczyk, Dawid  */
5468d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5471abe55efSEd Tanous {
54855c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5491e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5501e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5511e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5521e1e598dSJonathan Doman         "CurrentHostState",
553*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
5541e1e598dSJonathan Doman                 const std::string& hostState) {
5551abe55efSEd Tanous         if (ec)
5561abe55efSEd Tanous         {
55722228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
55822228c28SAndrew Geissler             {
55922228c28SAndrew Geissler                 // Service not available, no error, just don't return
56022228c28SAndrew Geissler                 // host state info
56122228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
56222228c28SAndrew Geissler                 return;
56322228c28SAndrew Geissler             }
56422228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
565f12894f8SJason M. Bills             messages::internalError(aResp->res);
566c5b2abe0SLewanczyk, Dawid             return;
567c5b2abe0SLewanczyk, Dawid         }
5686617338dSEd Tanous 
5691e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
570c5b2abe0SLewanczyk, Dawid         // Verify Host State
5711e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5721abe55efSEd Tanous         {
57355c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "On";
5746617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Enabled";
5751abe55efSEd Tanous         }
5761e1e598dSJonathan Doman         else if (hostState ==
5770fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
5788c888608SGunnar Mills         {
5798c888608SGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
5808c888608SGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Quiesced";
5818c888608SGunnar Mills         }
5821e1e598dSJonathan Doman         else if (hostState ==
5830fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
58483935af9SAndrew Geissler         {
58583935af9SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "On";
58683935af9SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "InTest";
58783935af9SAndrew Geissler         }
5880fda0f12SGeorge Liu         else if (
5891e1e598dSJonathan Doman             hostState ==
5900fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5911a2a1437SAndrew Geissler         {
5921a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOn";
59315c27bf8SNoah Brewer             aResp->res.jsonValue["Status"]["State"] = "Starting";
5941a2a1437SAndrew Geissler         }
595002d39b4SEd Tanous         else if (hostState ==
5960fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5971a2a1437SAndrew Geissler         {
5981a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOff";
5991a2a1437SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "Disabled";
6001a2a1437SAndrew Geissler         }
6011abe55efSEd Tanous         else
6021abe55efSEd Tanous         {
60355c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "Off";
6046617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Disabled";
605c5b2abe0SLewanczyk, Dawid         }
6061e1e598dSJonathan Doman         });
607c5b2abe0SLewanczyk, Dawid }
608c5b2abe0SLewanczyk, Dawid 
609c5b2abe0SLewanczyk, Dawid /**
610786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
611491d8ee7SSantosh Puranik  *
612491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
613491d8ee7SSantosh Puranik  *
614491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
615491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
616491d8ee7SSantosh Puranik  */
61723a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
618491d8ee7SSantosh Puranik {
619491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
620491d8ee7SSantosh Puranik     {
621491d8ee7SSantosh Puranik         return "None";
622491d8ee7SSantosh Puranik     }
6233174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
624491d8ee7SSantosh Puranik     {
625491d8ee7SSantosh Puranik         return "Hdd";
626491d8ee7SSantosh Puranik     }
6273174e4dfSEd Tanous     if (dbusSource ==
628a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
629491d8ee7SSantosh Puranik     {
630491d8ee7SSantosh Puranik         return "Cd";
631491d8ee7SSantosh Puranik     }
6323174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
633491d8ee7SSantosh Puranik     {
634491d8ee7SSantosh Puranik         return "Pxe";
635491d8ee7SSantosh Puranik     }
6363174e4dfSEd Tanous     if (dbusSource ==
637944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6389f16b2c1SJennifer Lee     {
6399f16b2c1SJennifer Lee         return "Usb";
6409f16b2c1SJennifer Lee     }
641491d8ee7SSantosh Puranik     return "";
642491d8ee7SSantosh Puranik }
643491d8ee7SSantosh Puranik 
644491d8ee7SSantosh Puranik /**
645cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
646cd9a4666SKonstantin Aladyshev  *
647cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
648cd9a4666SKonstantin Aladyshev  *
649cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
650cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
651cd9a4666SKonstantin Aladyshev  */
652cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
653cd9a4666SKonstantin Aladyshev {
654cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
655cd9a4666SKonstantin Aladyshev     {
656cd9a4666SKonstantin Aladyshev         return "Legacy";
657cd9a4666SKonstantin Aladyshev     }
658cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
659cd9a4666SKonstantin Aladyshev     {
660cd9a4666SKonstantin Aladyshev         return "UEFI";
661cd9a4666SKonstantin Aladyshev     }
662cd9a4666SKonstantin Aladyshev     return "";
663cd9a4666SKonstantin Aladyshev }
664cd9a4666SKonstantin Aladyshev 
665cd9a4666SKonstantin Aladyshev /**
666786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
667491d8ee7SSantosh Puranik  *
668491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
669491d8ee7SSantosh Puranik  *
670491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
671491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
672491d8ee7SSantosh Puranik  */
67323a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
674491d8ee7SSantosh Puranik {
675491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
676491d8ee7SSantosh Puranik     {
677491d8ee7SSantosh Puranik         return "None";
678491d8ee7SSantosh Puranik     }
6793174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
680491d8ee7SSantosh Puranik     {
681491d8ee7SSantosh Puranik         return "Diags";
682491d8ee7SSantosh Puranik     }
6833174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
684491d8ee7SSantosh Puranik     {
685491d8ee7SSantosh Puranik         return "BiosSetup";
686491d8ee7SSantosh Puranik     }
687491d8ee7SSantosh Puranik     return "";
688491d8ee7SSantosh Puranik }
689491d8ee7SSantosh Puranik 
690491d8ee7SSantosh Puranik /**
691e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
692e43914b3SAndrew Geissler  *
693e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
694e43914b3SAndrew Geissler  *
695e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
696e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
697e43914b3SAndrew Geissler  */
698e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
699e43914b3SAndrew Geissler {
700e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
701e43914b3SAndrew Geissler     // enum
702e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
703e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
704e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
705e43914b3SAndrew Geissler     {
706e43914b3SAndrew Geissler         rfBpLastState = "None";
707e43914b3SAndrew Geissler     }
708e43914b3SAndrew Geissler     else if (dbusBootProgress ==
709e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
710e43914b3SAndrew Geissler              "PrimaryProcInit")
711e43914b3SAndrew Geissler     {
712e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
713e43914b3SAndrew Geissler     }
714e43914b3SAndrew Geissler     else if (dbusBootProgress ==
715e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
716e43914b3SAndrew Geissler              "BusInit")
717e43914b3SAndrew Geissler     {
718e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
719e43914b3SAndrew Geissler     }
720e43914b3SAndrew Geissler     else if (dbusBootProgress ==
721e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
722e43914b3SAndrew Geissler              "MemoryInit")
723e43914b3SAndrew Geissler     {
724e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
725e43914b3SAndrew Geissler     }
726e43914b3SAndrew Geissler     else if (dbusBootProgress ==
727e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
728e43914b3SAndrew Geissler              "SecondaryProcInit")
729e43914b3SAndrew Geissler     {
730e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
731e43914b3SAndrew Geissler     }
732e43914b3SAndrew Geissler     else if (dbusBootProgress ==
733e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
734e43914b3SAndrew Geissler              "PCIInit")
735e43914b3SAndrew Geissler     {
736e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
737e43914b3SAndrew Geissler     }
738e43914b3SAndrew Geissler     else if (dbusBootProgress ==
739e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
740e43914b3SAndrew Geissler              "SystemSetup")
741e43914b3SAndrew Geissler     {
742e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
743e43914b3SAndrew Geissler     }
744e43914b3SAndrew Geissler     else if (dbusBootProgress ==
745e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
746e43914b3SAndrew Geissler              "SystemInitComplete")
747e43914b3SAndrew Geissler     {
748e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
749e43914b3SAndrew Geissler     }
750e43914b3SAndrew Geissler     else if (dbusBootProgress ==
751e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
752e43914b3SAndrew Geissler              "OSStart")
753e43914b3SAndrew Geissler     {
754e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
755e43914b3SAndrew Geissler     }
756e43914b3SAndrew Geissler     else if (dbusBootProgress ==
757e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
758e43914b3SAndrew Geissler              "OSRunning")
759e43914b3SAndrew Geissler     {
760e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
761e43914b3SAndrew Geissler     }
762e43914b3SAndrew Geissler     else
763e43914b3SAndrew Geissler     {
764e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
765e43914b3SAndrew Geissler                          << dbusBootProgress;
766e43914b3SAndrew Geissler         // Just return the default
767e43914b3SAndrew Geissler     }
768e43914b3SAndrew Geissler     return rfBpLastState;
769e43914b3SAndrew Geissler }
770e43914b3SAndrew Geissler 
771e43914b3SAndrew Geissler /**
772786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
773491d8ee7SSantosh Puranik  *
774491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
775944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
776944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
777491d8ee7SSantosh Puranik  *
778944ffaf9SJohnathan Mantey  * @return Integer error code.
779491d8ee7SSantosh Puranik  */
7808d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
781944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
782944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
783491d8ee7SSantosh Puranik {
784c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
785c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
786944ffaf9SJohnathan Mantey 
787491d8ee7SSantosh Puranik     if (rfSource == "None")
788491d8ee7SSantosh Puranik     {
789944ffaf9SJohnathan Mantey         return 0;
790491d8ee7SSantosh Puranik     }
7913174e4dfSEd Tanous     if (rfSource == "Pxe")
792491d8ee7SSantosh Puranik     {
793944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
794944ffaf9SJohnathan Mantey     }
795944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
796944ffaf9SJohnathan Mantey     {
797944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
798944ffaf9SJohnathan Mantey     }
799944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
800944ffaf9SJohnathan Mantey     {
801944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
802944ffaf9SJohnathan Mantey     }
803944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
804944ffaf9SJohnathan Mantey     {
805944ffaf9SJohnathan Mantey         bootSource =
806944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
807944ffaf9SJohnathan Mantey     }
808944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
809944ffaf9SJohnathan Mantey     {
810944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
811491d8ee7SSantosh Puranik     }
8129f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8139f16b2c1SJennifer Lee     {
814944ffaf9SJohnathan Mantey         bootSource =
815944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8169f16b2c1SJennifer Lee     }
817491d8ee7SSantosh Puranik     else
818491d8ee7SSantosh Puranik     {
8190fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8200fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
821944ffaf9SJohnathan Mantey             << bootSource;
822944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
823944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
824944ffaf9SJohnathan Mantey         return -1;
825491d8ee7SSantosh Puranik     }
826944ffaf9SJohnathan Mantey     return 0;
827491d8ee7SSantosh Puranik }
8281981771bSAli Ahmed 
829978b8803SAndrew Geissler /**
830978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
831978b8803SAndrew Geissler  *
832978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
833978b8803SAndrew Geissler  *
834978b8803SAndrew Geissler  * @return None.
835978b8803SAndrew Geissler  */
8368d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
837978b8803SAndrew Geissler {
8381e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8391e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8401e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8411e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
842*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
8431e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
844978b8803SAndrew Geissler         if (ec)
845978b8803SAndrew Geissler         {
846978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
847978b8803SAndrew Geissler             // not found
848978b8803SAndrew Geissler             return;
849978b8803SAndrew Geissler         }
850978b8803SAndrew Geissler 
8511e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
852978b8803SAndrew Geissler 
853e43914b3SAndrew Geissler         aResp->res.jsonValue["BootProgress"]["LastState"] =
854e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8551e1e598dSJonathan Doman         });
856978b8803SAndrew Geissler }
857491d8ee7SSantosh Puranik 
858491d8ee7SSantosh Puranik /**
859b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
860b6d5d45cSHieu Huynh  *
861b6d5d45cSHieu Huynh  * @param[in] aResp  Shared pointer for generating response message.
862b6d5d45cSHieu Huynh  *
863b6d5d45cSHieu Huynh  * @return None.
864b6d5d45cSHieu Huynh  */
865b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
866b6d5d45cSHieu Huynh     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
867b6d5d45cSHieu Huynh {
868b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
869b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
870b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
871b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
872*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
873b6d5d45cSHieu Huynh                 const uint64_t lastStateTime) {
874b6d5d45cSHieu Huynh         if (ec)
875b6d5d45cSHieu Huynh         {
876b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
877b6d5d45cSHieu Huynh             return;
878b6d5d45cSHieu Huynh         }
879b6d5d45cSHieu Huynh 
880b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
881b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
882b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
883b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
884b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
885b6d5d45cSHieu Huynh 
886b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
887b6d5d45cSHieu Huynh         aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
888b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
889b6d5d45cSHieu Huynh         });
890b6d5d45cSHieu Huynh }
891b6d5d45cSHieu Huynh 
892b6d5d45cSHieu Huynh /**
893c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
894cd9a4666SKonstantin Aladyshev  *
895cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
896cd9a4666SKonstantin Aladyshev  *
897cd9a4666SKonstantin Aladyshev  * @return None.
898cd9a4666SKonstantin Aladyshev  */
899cd9a4666SKonstantin Aladyshev 
900c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
901cd9a4666SKonstantin Aladyshev {
9021e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9031e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9041e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9051e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
906*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9071e1e598dSJonathan Doman                 const std::string& bootType) {
908cd9a4666SKonstantin Aladyshev         if (ec)
909cd9a4666SKonstantin Aladyshev         {
910cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
911cd9a4666SKonstantin Aladyshev             return;
912cd9a4666SKonstantin Aladyshev         }
913cd9a4666SKonstantin Aladyshev 
9141e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
915cd9a4666SKonstantin Aladyshev 
916002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
917002d39b4SEd Tanous                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
918613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
919cd9a4666SKonstantin Aladyshev 
9201e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
921cd9a4666SKonstantin Aladyshev         if (rfType.empty())
922cd9a4666SKonstantin Aladyshev         {
923cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
924cd9a4666SKonstantin Aladyshev             return;
925cd9a4666SKonstantin Aladyshev         }
926cd9a4666SKonstantin Aladyshev 
927cd9a4666SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9281e1e598dSJonathan Doman         });
929cd9a4666SKonstantin Aladyshev }
930cd9a4666SKonstantin Aladyshev 
931cd9a4666SKonstantin Aladyshev /**
932c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
933491d8ee7SSantosh Puranik  *
934491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
935491d8ee7SSantosh Puranik  *
936491d8ee7SSantosh Puranik  * @return None.
937491d8ee7SSantosh Puranik  */
938c21865c4SKonstantin Aladyshev 
939c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
940491d8ee7SSantosh Puranik {
9411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9421e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9431e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9441e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
945*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9461e1e598dSJonathan Doman                 const std::string& bootModeStr) {
947491d8ee7SSantosh Puranik         if (ec)
948491d8ee7SSantosh Puranik         {
949491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
950491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
951491d8ee7SSantosh Puranik             return;
952491d8ee7SSantosh Puranik         }
953491d8ee7SSantosh Puranik 
9541e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
955491d8ee7SSantosh Puranik 
9560fda0f12SGeorge Liu         aResp->res
9570fda0f12SGeorge Liu             .jsonValue["Boot"]
958002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
959002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
960491d8ee7SSantosh Puranik 
9611e1e598dSJonathan Doman         if (bootModeStr !=
962491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
963491d8ee7SSantosh Puranik         {
9641e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
965491d8ee7SSantosh Puranik             if (!rfMode.empty())
966491d8ee7SSantosh Puranik             {
967491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
968491d8ee7SSantosh Puranik                     rfMode;
969491d8ee7SSantosh Puranik             }
970491d8ee7SSantosh Puranik         }
9711e1e598dSJonathan Doman         });
972491d8ee7SSantosh Puranik }
973491d8ee7SSantosh Puranik 
974491d8ee7SSantosh Puranik /**
975c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
976491d8ee7SSantosh Puranik  *
977491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
978491d8ee7SSantosh Puranik  *
979491d8ee7SSantosh Puranik  * @return None.
980491d8ee7SSantosh Puranik  */
981c21865c4SKonstantin Aladyshev 
982c21865c4SKonstantin Aladyshev inline void
983c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
984491d8ee7SSantosh Puranik {
9851e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9861e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9871e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9881e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
989*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9901e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
991491d8ee7SSantosh Puranik         if (ec)
992491d8ee7SSantosh Puranik         {
993491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
9945ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
9955ef735c8SNan Zhou             {
9965ef735c8SNan Zhou                 return;
9975ef735c8SNan Zhou             }
998491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
999491d8ee7SSantosh Puranik             return;
1000491d8ee7SSantosh Puranik         }
1001491d8ee7SSantosh Puranik 
10021e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1003491d8ee7SSantosh Puranik 
10041e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1005491d8ee7SSantosh Puranik         if (!rfSource.empty())
1006491d8ee7SSantosh Puranik         {
1007002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1008491d8ee7SSantosh Puranik         }
1009cd9a4666SKonstantin Aladyshev 
1010cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1011cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1012c21865c4SKonstantin Aladyshev         getBootOverrideMode(aResp);
10131e1e598dSJonathan Doman         });
1014491d8ee7SSantosh Puranik }
1015491d8ee7SSantosh Puranik 
1016491d8ee7SSantosh Puranik /**
1017c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1018c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1019c21865c4SKonstantin Aladyshev  * state
1020491d8ee7SSantosh Puranik  *
1021491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1022491d8ee7SSantosh Puranik  *
1023491d8ee7SSantosh Puranik  * @return None.
1024491d8ee7SSantosh Puranik  */
1025491d8ee7SSantosh Puranik 
1026c21865c4SKonstantin Aladyshev inline void
1027c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1028c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1029c21865c4SKonstantin Aladyshev {
1030c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1031c21865c4SKonstantin Aladyshev     {
1032c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1033c21865c4SKonstantin Aladyshev         return;
1034c21865c4SKonstantin Aladyshev     }
1035c21865c4SKonstantin Aladyshev 
1036c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1037c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10381e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10391e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10401e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10411e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1042*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1043491d8ee7SSantosh Puranik         if (ec)
1044491d8ee7SSantosh Puranik         {
1045491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1046c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1047491d8ee7SSantosh Puranik             return;
1048491d8ee7SSantosh Puranik         }
1049491d8ee7SSantosh Puranik 
1050c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1051c21865c4SKonstantin Aladyshev         {
1052002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1053c21865c4SKonstantin Aladyshev         }
1054c21865c4SKonstantin Aladyshev         else
1055c21865c4SKonstantin Aladyshev         {
1056c21865c4SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1057c21865c4SKonstantin Aladyshev                 "Continuous";
1058c21865c4SKonstantin Aladyshev         }
10591e1e598dSJonathan Doman         });
1060491d8ee7SSantosh Puranik }
1061491d8ee7SSantosh Puranik 
1062491d8ee7SSantosh Puranik /**
1063c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1064c21865c4SKonstantin Aladyshev  *
1065c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1066c21865c4SKonstantin Aladyshev  *
1067c21865c4SKonstantin Aladyshev  * @return None.
1068c21865c4SKonstantin Aladyshev  */
1069c21865c4SKonstantin Aladyshev 
1070c21865c4SKonstantin Aladyshev inline void
1071c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1072c21865c4SKonstantin Aladyshev {
10731e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10741e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10751e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10761e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1077*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
10781e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1079c21865c4SKonstantin Aladyshev         if (ec)
1080c21865c4SKonstantin Aladyshev         {
1081c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10825ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10835ef735c8SNan Zhou             {
10845ef735c8SNan Zhou                 return;
10855ef735c8SNan Zhou             }
1086c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1087c21865c4SKonstantin Aladyshev             return;
1088c21865c4SKonstantin Aladyshev         }
1089c21865c4SKonstantin Aladyshev 
10901e1e598dSJonathan Doman         processBootOverrideEnable(aResp, bootOverrideEnable);
10911e1e598dSJonathan Doman         });
1092c21865c4SKonstantin Aladyshev }
1093c21865c4SKonstantin Aladyshev 
1094c21865c4SKonstantin Aladyshev /**
1095c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1096c21865c4SKonstantin Aladyshev  *
1097c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1098c21865c4SKonstantin Aladyshev  *
1099c21865c4SKonstantin Aladyshev  * @return None.
1100c21865c4SKonstantin Aladyshev  */
1101c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1102c21865c4SKonstantin Aladyshev {
1103c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1104c21865c4SKonstantin Aladyshev 
1105c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1106c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1107c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1108c21865c4SKonstantin Aladyshev }
1109c21865c4SKonstantin Aladyshev 
1110c21865c4SKonstantin Aladyshev /**
1111c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1112c0557e1aSGunnar Mills  *
1113c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1114c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1115c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1116c0557e1aSGunnar Mills  * last power operation time.
1117c0557e1aSGunnar Mills  *
1118c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1119c0557e1aSGunnar Mills  *
1120c0557e1aSGunnar Mills  * @return None.
1121c0557e1aSGunnar Mills  */
11228d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1123c0557e1aSGunnar Mills {
1124c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1125c0557e1aSGunnar Mills 
11261e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11271e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11281e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11291e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1130*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) {
1131c0557e1aSGunnar Mills         if (ec)
1132c0557e1aSGunnar Mills         {
1133c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1134c0557e1aSGunnar Mills             return;
1135c0557e1aSGunnar Mills         }
1136c0557e1aSGunnar Mills 
1137c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1138c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11391e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1140c0557e1aSGunnar Mills 
1141c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1142c0557e1aSGunnar Mills         aResp->res.jsonValue["LastResetTime"] =
11432b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11441e1e598dSJonathan Doman         });
1145c0557e1aSGunnar Mills }
1146c0557e1aSGunnar Mills 
1147c0557e1aSGunnar Mills /**
11486bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11496bd5a8d2SGunnar Mills  *
11506bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11516bd5a8d2SGunnar Mills  *
11526bd5a8d2SGunnar Mills  * @return None.
11536bd5a8d2SGunnar Mills  */
11548d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11556bd5a8d2SGunnar Mills {
11566bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
11576bd5a8d2SGunnar Mills 
11581e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11591e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11601e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
11611e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1162*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) {
11636bd5a8d2SGunnar Mills         if (ec)
11646bd5a8d2SGunnar Mills         {
11656bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
11666bd5a8d2SGunnar Mills             return;
11676bd5a8d2SGunnar Mills         }
11686bd5a8d2SGunnar Mills 
11691e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1170e05aec50SEd Tanous         if (autoRebootEnabled)
11716bd5a8d2SGunnar Mills         {
11726bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11736bd5a8d2SGunnar Mills                 "RetryAttempts";
11746bd5a8d2SGunnar Mills             // If AutomaticRetry (AutoReboot) is enabled see how many
11756bd5a8d2SGunnar Mills             // attempts are left
11761e1e598dSJonathan Doman             sdbusplus::asio::getProperty<uint32_t>(
1177002d39b4SEd Tanous                 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
11781e1e598dSJonathan Doman                 "/xyz/openbmc_project/state/host0",
11791e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.Boot.RebootAttempts",
11801e1e598dSJonathan Doman                 "AttemptsLeft",
1181*5e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2,
1182914e2d5dSEd Tanous                         const uint32_t autoRebootAttemptsLeft) {
1183cb13a392SEd Tanous                 if (ec2)
11846bd5a8d2SGunnar Mills                 {
1185cb13a392SEd Tanous                     BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
11866bd5a8d2SGunnar Mills                     return;
11876bd5a8d2SGunnar Mills                 }
11886bd5a8d2SGunnar Mills 
11896bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
11901e1e598dSJonathan Doman                                  << autoRebootAttemptsLeft;
11916bd5a8d2SGunnar Mills 
11926bd5a8d2SGunnar Mills                 aResp->res
1193002d39b4SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
11941e1e598dSJonathan Doman                     autoRebootAttemptsLeft;
11951e1e598dSJonathan Doman                 });
11966bd5a8d2SGunnar Mills         }
11976bd5a8d2SGunnar Mills         else
11986bd5a8d2SGunnar Mills         {
1199002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
12006bd5a8d2SGunnar Mills         }
12016bd5a8d2SGunnar Mills 
12026bd5a8d2SGunnar Mills         // Not on D-Bus. Hardcoded here:
12036bd5a8d2SGunnar Mills         // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
12046bd5a8d2SGunnar Mills         aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
120569f35306SGunnar Mills 
120669f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
120769f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
120869f35306SGunnar Mills         // RetryAttempts.
1209002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
12100fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
12110fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
12121e1e598dSJonathan Doman         });
12136bd5a8d2SGunnar Mills }
12146bd5a8d2SGunnar Mills 
12156bd5a8d2SGunnar Mills /**
1216c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1217c6a620f2SGeorge Liu  *
1218c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1219c6a620f2SGeorge Liu  *
1220c6a620f2SGeorge Liu  * @return None.
1221c6a620f2SGeorge Liu  */
12228d1b46d7Szhanghch05 inline void
12238d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1224c6a620f2SGeorge Liu {
1225c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1226c6a620f2SGeorge Liu 
12271e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
12281e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12291e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
12301e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1231*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
1232*5e7e2dc5SEd Tanous                 const std::string& policy) {
1233c6a620f2SGeorge Liu         if (ec)
1234c6a620f2SGeorge Liu         {
1235c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1236c6a620f2SGeorge Liu             return;
1237c6a620f2SGeorge Liu         }
1238c6a620f2SGeorge Liu 
12390fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
12400fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1241c6a620f2SGeorge Liu              "AlwaysOn"},
12420fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1243c6a620f2SGeorge Liu              "AlwaysOff"},
12440fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
12454ed47cb8SMatthew Barth              "LastState"},
12464ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
12474ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
12484ed47cb8SMatthew Barth              "AlwaysOff"}};
1249c6a620f2SGeorge Liu 
12501e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1251c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1252c6a620f2SGeorge Liu         {
1253c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1254c6a620f2SGeorge Liu             return;
1255c6a620f2SGeorge Liu         }
1256c6a620f2SGeorge Liu 
1257c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
12581e1e598dSJonathan Doman         });
1259c6a620f2SGeorge Liu }
1260c6a620f2SGeorge Liu 
1261c6a620f2SGeorge Liu /**
12621981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
12631981771bSAli Ahmed  * TPM is required for booting the host.
12641981771bSAli Ahmed  *
12651981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
12661981771bSAli Ahmed  *
12671981771bSAli Ahmed  * @return None.
12681981771bSAli Ahmed  */
12691981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
12701981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12711981771bSAli Ahmed {
12721981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1273e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1274e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1275e99073f5SGeorge Liu     dbus::utility::getSubTree(
1276e99073f5SGeorge Liu         "/", 0, interfaces,
1277e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1278b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
12791981771bSAli Ahmed         if (ec)
12801981771bSAli Ahmed         {
1281002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1282002d39b4SEd Tanous                              << ec;
12831981771bSAli Ahmed             // This is an optional D-Bus object so just return if
12841981771bSAli Ahmed             // error occurs
12851981771bSAli Ahmed             return;
12861981771bSAli Ahmed         }
128726f6976fSEd Tanous         if (subtree.empty())
12881981771bSAli Ahmed         {
12891981771bSAli Ahmed             // As noted above, this is an optional interface so just return
12901981771bSAli Ahmed             // if there is no instance found
12911981771bSAli Ahmed             return;
12921981771bSAli Ahmed         }
12931981771bSAli Ahmed 
12941981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
12951981771bSAli Ahmed         if (subtree.size() > 1)
12961981771bSAli Ahmed         {
12971981771bSAli Ahmed             BMCWEB_LOG_DEBUG
12981981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
12991981771bSAli Ahmed                 << subtree.size();
13001981771bSAli Ahmed             // Throw an internal Error and return
13011981771bSAli Ahmed             messages::internalError(aResp->res);
13021981771bSAli Ahmed             return;
13031981771bSAli Ahmed         }
13041981771bSAli Ahmed 
13051981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13061981771bSAli Ahmed         // field
13071981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13081981771bSAli Ahmed         {
13091981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13101981771bSAli Ahmed             messages::internalError(aResp->res);
13111981771bSAli Ahmed             return;
13121981771bSAli Ahmed         }
13131981771bSAli Ahmed 
13141981771bSAli Ahmed         const std::string& path = subtree[0].first;
13151981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
13161981771bSAli Ahmed 
13171981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
13181e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
13191e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
13201e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1321*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
13228a592810SEd Tanous             if (ec2)
13231981771bSAli Ahmed             {
1324002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
13258a592810SEd Tanous                                  << ec2;
13261981771bSAli Ahmed                 messages::internalError(aResp->res);
13271981771bSAli Ahmed                 return;
13281981771bSAli Ahmed             }
13291981771bSAli Ahmed 
13301e1e598dSJonathan Doman             if (tpmRequired)
13311981771bSAli Ahmed             {
1332002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
13331981771bSAli Ahmed                     "Required";
13341981771bSAli Ahmed             }
13351981771bSAli Ahmed             else
13361981771bSAli Ahmed             {
1337002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
13381981771bSAli Ahmed                     "Disabled";
13391981771bSAli Ahmed             }
13401e1e598dSJonathan Doman             });
1341e99073f5SGeorge Liu         });
13421981771bSAli Ahmed }
13431981771bSAli Ahmed 
13441981771bSAli Ahmed /**
13451c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
13461c05dae3SAli Ahmed  * TPM is required for booting the host.
13471c05dae3SAli Ahmed  *
13481c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
13491c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
13501c05dae3SAli Ahmed  *
13511c05dae3SAli Ahmed  * @return None.
13521c05dae3SAli Ahmed  */
13531c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
13541c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
13551c05dae3SAli Ahmed {
13561c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1357e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1358e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1359e99073f5SGeorge Liu     dbus::utility::getSubTree(
1360e99073f5SGeorge Liu         "/", 0, interfaces,
1361e99073f5SGeorge Liu         [aResp,
1362e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1363e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
13641c05dae3SAli Ahmed         if (ec)
13651c05dae3SAli Ahmed         {
1366002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1367002d39b4SEd Tanous                              << ec;
13681c05dae3SAli Ahmed             messages::internalError(aResp->res);
13691c05dae3SAli Ahmed             return;
13701c05dae3SAli Ahmed         }
137126f6976fSEd Tanous         if (subtree.empty())
13721c05dae3SAli Ahmed         {
13731c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
13741c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
13751c05dae3SAli Ahmed             return;
13761c05dae3SAli Ahmed         }
13771c05dae3SAli Ahmed 
13781c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
13791c05dae3SAli Ahmed         if (subtree.size() > 1)
13801c05dae3SAli Ahmed         {
13811c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
13821c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13831c05dae3SAli Ahmed                 << subtree.size();
13841c05dae3SAli Ahmed             // Throw an internal Error and return
13851c05dae3SAli Ahmed             messages::internalError(aResp->res);
13861c05dae3SAli Ahmed             return;
13871c05dae3SAli Ahmed         }
13881c05dae3SAli Ahmed 
13891c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13901c05dae3SAli Ahmed         // field
13911c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13921c05dae3SAli Ahmed         {
13931c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13941c05dae3SAli Ahmed             messages::internalError(aResp->res);
13951c05dae3SAli Ahmed             return;
13961c05dae3SAli Ahmed         }
13971c05dae3SAli Ahmed 
13981c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
13991c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14001c05dae3SAli Ahmed 
14011c05dae3SAli Ahmed         if (serv.empty())
14021c05dae3SAli Ahmed         {
14031c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
14041c05dae3SAli Ahmed             messages::internalError(aResp->res);
14051c05dae3SAli Ahmed             return;
14061c05dae3SAli Ahmed         }
14071c05dae3SAli Ahmed 
14081c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
14091c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
1410*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
14118a592810SEd Tanous             if (ec2)
14121c05dae3SAli Ahmed             {
14130fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
14140fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
14158a592810SEd Tanous                     << ec2;
14161c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14171c05dae3SAli Ahmed                 return;
14181c05dae3SAli Ahmed             }
14191c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
14201c05dae3SAli Ahmed             },
14211c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
14221c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1423168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
1424e99073f5SGeorge Liu         });
14251c05dae3SAli Ahmed }
14261c05dae3SAli Ahmed 
14271c05dae3SAli Ahmed /**
1428491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1429491d8ee7SSantosh Puranik  *
1430491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1431cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1432cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1433cd9a4666SKonstantin Aladyshev  */
1434cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1435cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1436cd9a4666SKonstantin Aladyshev {
1437c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1438cd9a4666SKonstantin Aladyshev 
1439c21865c4SKonstantin Aladyshev     if (!bootType)
1440cd9a4666SKonstantin Aladyshev     {
1441c21865c4SKonstantin Aladyshev         return;
1442c21865c4SKonstantin Aladyshev     }
1443c21865c4SKonstantin Aladyshev 
1444cd9a4666SKonstantin Aladyshev     // Source target specified
1445cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1446cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1447cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1448cd9a4666SKonstantin Aladyshev     {
1449cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1450cd9a4666SKonstantin Aladyshev     }
1451cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1452cd9a4666SKonstantin Aladyshev     {
1453cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1454cd9a4666SKonstantin Aladyshev     }
1455cd9a4666SKonstantin Aladyshev     else
1456cd9a4666SKonstantin Aladyshev     {
1457cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1458cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1459cd9a4666SKonstantin Aladyshev                          << *bootType;
1460cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1461cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1462cd9a4666SKonstantin Aladyshev         return;
1463cd9a4666SKonstantin Aladyshev     }
1464cd9a4666SKonstantin Aladyshev 
1465cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1466cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1467cd9a4666SKonstantin Aladyshev 
1468cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1469*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1470cd9a4666SKonstantin Aladyshev         if (ec)
1471cd9a4666SKonstantin Aladyshev         {
1472cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1473cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1474cd9a4666SKonstantin Aladyshev             {
1475cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1476cd9a4666SKonstantin Aladyshev                 return;
1477cd9a4666SKonstantin Aladyshev             }
1478cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1479cd9a4666SKonstantin Aladyshev             return;
1480cd9a4666SKonstantin Aladyshev         }
1481cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1482cd9a4666SKonstantin Aladyshev         },
1483c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1484c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1485cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1486cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1487168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1488cd9a4666SKonstantin Aladyshev }
1489cd9a4666SKonstantin Aladyshev 
1490cd9a4666SKonstantin Aladyshev /**
1491cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1492cd9a4666SKonstantin Aladyshev  *
1493cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1494c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1495c21865c4SKonstantin Aladyshev  * @return Integer error code.
1496c21865c4SKonstantin Aladyshev  */
1497c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1498c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1499c21865c4SKonstantin Aladyshev {
1500c21865c4SKonstantin Aladyshev     if (!bootEnable)
1501c21865c4SKonstantin Aladyshev     {
1502c21865c4SKonstantin Aladyshev         return;
1503c21865c4SKonstantin Aladyshev     }
1504c21865c4SKonstantin Aladyshev     // Source target specified
1505c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1506c21865c4SKonstantin Aladyshev 
1507c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1508c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1509c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1510c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1511c21865c4SKonstantin Aladyshev     {
1512c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1513c21865c4SKonstantin Aladyshev     }
1514c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1515c21865c4SKonstantin Aladyshev     {
1516c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1517c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1518c21865c4SKonstantin Aladyshev     }
1519c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1520c21865c4SKonstantin Aladyshev     {
1521c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1522c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1523c21865c4SKonstantin Aladyshev     }
1524c21865c4SKonstantin Aladyshev     else
1525c21865c4SKonstantin Aladyshev     {
15260fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
15270fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1528c21865c4SKonstantin Aladyshev             << *bootEnable;
1529c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1530c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1531c21865c4SKonstantin Aladyshev         return;
1532c21865c4SKonstantin Aladyshev     }
1533c21865c4SKonstantin Aladyshev 
1534c21865c4SKonstantin Aladyshev     // Act on validated parameters
1535c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1536c21865c4SKonstantin Aladyshev 
1537c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1538*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec2) {
15398a592810SEd Tanous         if (ec2)
1540c21865c4SKonstantin Aladyshev         {
15418a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1542c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1543c21865c4SKonstantin Aladyshev             return;
1544c21865c4SKonstantin Aladyshev         }
1545c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1546c21865c4SKonstantin Aladyshev         },
1547c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1548c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1549c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1550c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1551168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1552c21865c4SKonstantin Aladyshev 
1553c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1554c21865c4SKonstantin Aladyshev     {
1555c21865c4SKonstantin Aladyshev         return;
1556c21865c4SKonstantin Aladyshev     }
1557c21865c4SKonstantin Aladyshev 
1558c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1559c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1560c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1561c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1562c21865c4SKonstantin Aladyshev 
1563c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1564*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1565c21865c4SKonstantin Aladyshev         if (ec)
1566c21865c4SKonstantin Aladyshev         {
1567c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1568c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1569c21865c4SKonstantin Aladyshev             return;
1570c21865c4SKonstantin Aladyshev         }
1571c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1572c21865c4SKonstantin Aladyshev         },
1573c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1574c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1575c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1576c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1577168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1578c21865c4SKonstantin Aladyshev }
1579c21865c4SKonstantin Aladyshev 
1580c21865c4SKonstantin Aladyshev /**
1581c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1582c21865c4SKonstantin Aladyshev  *
1583c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1584491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1585491d8ee7SSantosh Puranik  *
1586265c1602SJohnathan Mantey  * @return Integer error code.
1587491d8ee7SSantosh Puranik  */
1588cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1589cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1590491d8ee7SSantosh Puranik {
1591c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1592c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1593944ffaf9SJohnathan Mantey 
1594c21865c4SKonstantin Aladyshev     if (!bootSource)
1595491d8ee7SSantosh Puranik     {
1596c21865c4SKonstantin Aladyshev         return;
1597c21865c4SKonstantin Aladyshev     }
1598c21865c4SKonstantin Aladyshev 
1599491d8ee7SSantosh Puranik     // Source target specified
1600491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1601491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1602e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1603e662eae8SEd Tanous         0)
1604491d8ee7SSantosh Puranik     {
1605944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1606944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1607491d8ee7SSantosh Puranik             << *bootSource;
1608491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1609491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1610491d8ee7SSantosh Puranik         return;
1611491d8ee7SSantosh Puranik     }
1612491d8ee7SSantosh Puranik 
1613944ffaf9SJohnathan Mantey     // Act on validated parameters
1614944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1615944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1616944ffaf9SJohnathan Mantey 
1617491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1618*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1619491d8ee7SSantosh Puranik         if (ec)
1620491d8ee7SSantosh Puranik         {
1621491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1622491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1623491d8ee7SSantosh Puranik             return;
1624491d8ee7SSantosh Puranik         }
1625491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1626491d8ee7SSantosh Puranik         },
1627c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1628c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1629491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1630491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1631168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1632944ffaf9SJohnathan Mantey 
1633491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1634*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1635491d8ee7SSantosh Puranik         if (ec)
1636491d8ee7SSantosh Puranik         {
1637491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1638491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1639491d8ee7SSantosh Puranik             return;
1640491d8ee7SSantosh Puranik         }
1641491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1642491d8ee7SSantosh Puranik         },
1643c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1644c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1645491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1646491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1647168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1648cd9a4666SKonstantin Aladyshev }
1649944ffaf9SJohnathan Mantey 
1650cd9a4666SKonstantin Aladyshev /**
1651c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1652491d8ee7SSantosh Puranik  *
1653491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1654491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1655cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1656491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1657491d8ee7SSantosh Puranik  *
1658265c1602SJohnathan Mantey  * @return Integer error code.
1659491d8ee7SSantosh Puranik  */
1660c21865c4SKonstantin Aladyshev 
1661c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1662c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1663c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1664c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1665491d8ee7SSantosh Puranik {
1666491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1667491d8ee7SSantosh Puranik 
1668c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1669c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1670c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1671491d8ee7SSantosh Puranik }
1672491d8ee7SSantosh Puranik 
1673c6a620f2SGeorge Liu /**
167498e386ecSGunnar Mills  * @brief Sets AssetTag
167598e386ecSGunnar Mills  *
167698e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
167798e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
167898e386ecSGunnar Mills  *
167998e386ecSGunnar Mills  * @return None.
168098e386ecSGunnar Mills  */
16818d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
168298e386ecSGunnar Mills                         const std::string& assetTag)
168398e386ecSGunnar Mills {
1684e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1685e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1686e99073f5SGeorge Liu     dbus::utility::getSubTree(
1687e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1688b9d36b47SEd Tanous         [aResp,
1689e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1690b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
169198e386ecSGunnar Mills         if (ec)
169298e386ecSGunnar Mills         {
169398e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
169498e386ecSGunnar Mills             messages::internalError(aResp->res);
169598e386ecSGunnar Mills             return;
169698e386ecSGunnar Mills         }
169726f6976fSEd Tanous         if (subtree.empty())
169898e386ecSGunnar Mills         {
169998e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
170098e386ecSGunnar Mills             messages::internalError(aResp->res);
170198e386ecSGunnar Mills             return;
170298e386ecSGunnar Mills         }
170398e386ecSGunnar Mills         // Assume only 1 system D-Bus object
170498e386ecSGunnar Mills         // Throw an error if there is more than 1
170598e386ecSGunnar Mills         if (subtree.size() > 1)
170698e386ecSGunnar Mills         {
170798e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
170898e386ecSGunnar Mills             messages::internalError(aResp->res);
170998e386ecSGunnar Mills             return;
171098e386ecSGunnar Mills         }
171198e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
171298e386ecSGunnar Mills         {
171398e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
171498e386ecSGunnar Mills             messages::internalError(aResp->res);
171598e386ecSGunnar Mills             return;
171698e386ecSGunnar Mills         }
171798e386ecSGunnar Mills 
171898e386ecSGunnar Mills         const std::string& path = subtree[0].first;
171998e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
172098e386ecSGunnar Mills 
172198e386ecSGunnar Mills         if (service.empty())
172298e386ecSGunnar Mills         {
172398e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
172498e386ecSGunnar Mills             messages::internalError(aResp->res);
172598e386ecSGunnar Mills             return;
172698e386ecSGunnar Mills         }
172798e386ecSGunnar Mills 
172898e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
1729*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
173098e386ecSGunnar Mills             if (ec2)
173198e386ecSGunnar Mills             {
1732002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1733002d39b4SEd Tanous                                  << ec2;
173498e386ecSGunnar Mills                 messages::internalError(aResp->res);
173598e386ecSGunnar Mills                 return;
173698e386ecSGunnar Mills             }
173798e386ecSGunnar Mills             },
173898e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
173998e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1740168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
1741e99073f5SGeorge Liu         });
174298e386ecSGunnar Mills }
174398e386ecSGunnar Mills 
174498e386ecSGunnar Mills /**
174569f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
174669f35306SGunnar Mills  *
174769f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
174869f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
174969f35306SGunnar Mills  *
175069f35306SGunnar Mills  * @return None.
175169f35306SGunnar Mills  */
17528d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1753f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
175469f35306SGunnar Mills {
175569f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
175669f35306SGunnar Mills 
175769f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1758543f4400SEd Tanous     bool autoRebootEnabled = false;
175969f35306SGunnar Mills 
176069f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
176169f35306SGunnar Mills     {
176269f35306SGunnar Mills         autoRebootEnabled = false;
176369f35306SGunnar Mills     }
176469f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
176569f35306SGunnar Mills     {
176669f35306SGunnar Mills         autoRebootEnabled = true;
176769f35306SGunnar Mills     }
176869f35306SGunnar Mills     else
176969f35306SGunnar Mills     {
17700fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
177169f35306SGunnar Mills                          << automaticRetryConfig;
177269f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
177369f35306SGunnar Mills                                          "AutomaticRetryConfig");
177469f35306SGunnar Mills         return;
177569f35306SGunnar Mills     }
177669f35306SGunnar Mills 
177769f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
1778*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
177969f35306SGunnar Mills         if (ec)
178069f35306SGunnar Mills         {
178169f35306SGunnar Mills             messages::internalError(aResp->res);
178269f35306SGunnar Mills             return;
178369f35306SGunnar Mills         }
178469f35306SGunnar Mills         },
178569f35306SGunnar Mills         "xyz.openbmc_project.Settings",
178669f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
178769f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
178869f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1789168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
179069f35306SGunnar Mills }
179169f35306SGunnar Mills 
179269f35306SGunnar Mills /**
1793c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1794c6a620f2SGeorge Liu  *
1795c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1796c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1797c6a620f2SGeorge Liu  *
1798c6a620f2SGeorge Liu  * @return None.
1799c6a620f2SGeorge Liu  */
18008d1b46d7Szhanghch05 inline void
18018d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18024e69c904SGunnar Mills                           const std::string& policy)
1803c6a620f2SGeorge Liu {
1804c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1805c6a620f2SGeorge Liu 
1806c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
18070fda0f12SGeorge Liu         {"AlwaysOn",
18080fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
18090fda0f12SGeorge Liu         {"AlwaysOff",
18100fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
18110fda0f12SGeorge Liu         {"LastState",
18120fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1813c6a620f2SGeorge Liu 
1814c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1815c6a620f2SGeorge Liu 
18164e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1817c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1818c6a620f2SGeorge Liu     {
18194e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
18204e69c904SGunnar Mills                                          "PowerRestorePolicy");
1821c6a620f2SGeorge Liu         return;
1822c6a620f2SGeorge Liu     }
1823c6a620f2SGeorge Liu 
1824c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1825c6a620f2SGeorge Liu 
1826c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1827*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1828c6a620f2SGeorge Liu         if (ec)
1829c6a620f2SGeorge Liu         {
1830c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1831c6a620f2SGeorge Liu             return;
1832c6a620f2SGeorge Liu         }
1833c6a620f2SGeorge Liu         },
1834c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1835c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1836c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1837c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1838168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1839c6a620f2SGeorge Liu }
1840c6a620f2SGeorge Liu 
1841a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1842a6349918SAppaRao Puli /**
1843a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1844a6349918SAppaRao Puli  *
1845a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1846a6349918SAppaRao Puli  *
1847a6349918SAppaRao Puli  * @return None.
1848a6349918SAppaRao Puli  */
18498d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1850a6349918SAppaRao Puli {
1851a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1852bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1853bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1854bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
1855*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
1856b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1857b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1858b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
185950626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
186050626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
186150626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
186250626f4fSJames Feist 
1863a6349918SAppaRao Puli         if (ec)
1864a6349918SAppaRao Puli         {
1865a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1866b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1867b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1868a6349918SAppaRao Puli             return;
1869a6349918SAppaRao Puli         }
1870a6349918SAppaRao Puli 
1871a6349918SAppaRao Puli         const bool* provState = nullptr;
1872a6349918SAppaRao Puli         const bool* lockState = nullptr;
1873bc1d29deSKrzysztof Grobelny 
1874bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
18750d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
18760d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1877bc1d29deSKrzysztof Grobelny 
1878bc1d29deSKrzysztof Grobelny         if (!success)
1879a6349918SAppaRao Puli         {
1880bc1d29deSKrzysztof Grobelny             messages::internalError(aResp->res);
1881bc1d29deSKrzysztof Grobelny             return;
1882a6349918SAppaRao Puli         }
1883a6349918SAppaRao Puli 
1884a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1885a6349918SAppaRao Puli         {
1886a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1887a6349918SAppaRao Puli             messages::internalError(aResp->res);
1888a6349918SAppaRao Puli             return;
1889a6349918SAppaRao Puli         }
1890a6349918SAppaRao Puli 
1891a6349918SAppaRao Puli         if (*provState == true)
1892a6349918SAppaRao Puli         {
1893a6349918SAppaRao Puli             if (*lockState == true)
1894a6349918SAppaRao Puli             {
1895a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1896a6349918SAppaRao Puli             }
1897a6349918SAppaRao Puli             else
1898a6349918SAppaRao Puli             {
1899a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1900a6349918SAppaRao Puli             }
1901a6349918SAppaRao Puli         }
1902a6349918SAppaRao Puli         else
1903a6349918SAppaRao Puli         {
1904a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1905a6349918SAppaRao Puli         }
1906bc1d29deSKrzysztof Grobelny         });
1907a6349918SAppaRao Puli }
1908a6349918SAppaRao Puli #endif
1909a6349918SAppaRao Puli 
1910491d8ee7SSantosh Puranik /**
19113a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
19123a2d0424SChris Cain  *
19133a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19143a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
19153a2d0424SChris Cain  *
19163a2d0424SChris Cain  * @return None.
19173a2d0424SChris Cain  */
19183a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19193a2d0424SChris Cain                                const std::string& modeValue)
19203a2d0424SChris Cain {
19210fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
19223a2d0424SChris Cain     {
19233a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
19243a2d0424SChris Cain     }
19250fda0f12SGeorge Liu     else if (
19260fda0f12SGeorge Liu         modeValue ==
19270fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
19283a2d0424SChris Cain     {
19293a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
19303a2d0424SChris Cain     }
19310fda0f12SGeorge Liu     else if (modeValue ==
19320fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
19333a2d0424SChris Cain     {
19343a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
19353a2d0424SChris Cain     }
19360fda0f12SGeorge Liu     else if (modeValue ==
19370fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
19383a2d0424SChris Cain     {
19393a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
19403a2d0424SChris Cain     }
19413a2d0424SChris Cain     else
19423a2d0424SChris Cain     {
19433a2d0424SChris Cain         // Any other values would be invalid
19443a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
19453a2d0424SChris Cain         messages::internalError(aResp->res);
19463a2d0424SChris Cain     }
19473a2d0424SChris Cain }
19483a2d0424SChris Cain 
19493a2d0424SChris Cain /**
19503a2d0424SChris Cain  * @brief Retrieves system power mode
19513a2d0424SChris Cain  *
19523a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19533a2d0424SChris Cain  *
19543a2d0424SChris Cain  * @return None.
19553a2d0424SChris Cain  */
19563a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
19573a2d0424SChris Cain {
19583a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
19593a2d0424SChris Cain 
19603a2d0424SChris Cain     // Get Power Mode object path:
1961e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1962e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
1963e99073f5SGeorge Liu     dbus::utility::getSubTree(
1964e99073f5SGeorge Liu         "/", 0, interfaces,
1965e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1966b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
19673a2d0424SChris Cain         if (ec)
19683a2d0424SChris Cain         {
1969002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1970002d39b4SEd Tanous                              << ec;
19713a2d0424SChris Cain             // This is an optional D-Bus object so just return if
19723a2d0424SChris Cain             // error occurs
19733a2d0424SChris Cain             return;
19743a2d0424SChris Cain         }
19753a2d0424SChris Cain         if (subtree.empty())
19763a2d0424SChris Cain         {
19773a2d0424SChris Cain             // As noted above, this is an optional interface so just return
19783a2d0424SChris Cain             // if there is no instance found
19793a2d0424SChris Cain             return;
19803a2d0424SChris Cain         }
19813a2d0424SChris Cain         if (subtree.size() > 1)
19823a2d0424SChris Cain         {
19833a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
19843a2d0424SChris Cain             // error
19853a2d0424SChris Cain             BMCWEB_LOG_DEBUG
19863a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
19873a2d0424SChris Cain                 << subtree.size();
19883a2d0424SChris Cain             messages::internalError(aResp->res);
19893a2d0424SChris Cain             return;
19903a2d0424SChris Cain         }
19913a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
19923a2d0424SChris Cain         {
19933a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
19943a2d0424SChris Cain             messages::internalError(aResp->res);
19953a2d0424SChris Cain             return;
19963a2d0424SChris Cain         }
19973a2d0424SChris Cain         const std::string& path = subtree[0].first;
19983a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
19993a2d0424SChris Cain         if (service.empty())
20003a2d0424SChris Cain         {
20013a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20023a2d0424SChris Cain             messages::internalError(aResp->res);
20033a2d0424SChris Cain             return;
20043a2d0424SChris Cain         }
20053a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
20061e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
20071e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
20081e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2009*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
20101e1e598dSJonathan Doman                     const std::string& pmode) {
20118a592810SEd Tanous             if (ec2)
20123a2d0424SChris Cain             {
2013002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
20148a592810SEd Tanous                                  << ec2;
20153a2d0424SChris Cain                 messages::internalError(aResp->res);
20163a2d0424SChris Cain                 return;
20173a2d0424SChris Cain             }
20183a2d0424SChris Cain 
2019002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2020002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
20213a2d0424SChris Cain 
20221e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
20231e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
20241e1e598dSJonathan Doman             });
2025e99073f5SGeorge Liu         });
20263a2d0424SChris Cain }
20273a2d0424SChris Cain 
20283a2d0424SChris Cain /**
20293a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
20303a2d0424SChris Cain  * name associated with that string
20313a2d0424SChris Cain  *
20323a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20333a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
20343a2d0424SChris Cain  *
20353a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
20363a2d0424SChris Cain  */
20373a2d0424SChris Cain inline std::string
20383a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20393a2d0424SChris Cain                       const std::string& modeString)
20403a2d0424SChris Cain {
20413a2d0424SChris Cain     std::string mode;
20423a2d0424SChris Cain 
20433a2d0424SChris Cain     if (modeString == "Static")
20443a2d0424SChris Cain     {
20453a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
20463a2d0424SChris Cain     }
20473a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
20483a2d0424SChris Cain     {
20490fda0f12SGeorge Liu         mode =
20500fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
20513a2d0424SChris Cain     }
20523a2d0424SChris Cain     else if (modeString == "PowerSaving")
20533a2d0424SChris Cain     {
20543a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
20553a2d0424SChris Cain     }
20563a2d0424SChris Cain     else
20573a2d0424SChris Cain     {
20583a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
20593a2d0424SChris Cain     }
20603a2d0424SChris Cain     return mode;
20613a2d0424SChris Cain }
20623a2d0424SChris Cain 
20633a2d0424SChris Cain /**
20643a2d0424SChris Cain  * @brief Sets system power mode.
20653a2d0424SChris Cain  *
20663a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20673a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
20683a2d0424SChris Cain  *
20693a2d0424SChris Cain  * @return None.
20703a2d0424SChris Cain  */
20713a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20723a2d0424SChris Cain                          const std::string& pmode)
20733a2d0424SChris Cain {
20743a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
20753a2d0424SChris Cain 
20763a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
20773a2d0424SChris Cain     if (powerMode.empty())
20783a2d0424SChris Cain     {
20793a2d0424SChris Cain         return;
20803a2d0424SChris Cain     }
20813a2d0424SChris Cain 
20823a2d0424SChris Cain     // Get Power Mode object path:
2083e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2084e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2085e99073f5SGeorge Liu     dbus::utility::getSubTree(
2086e99073f5SGeorge Liu         "/", 0, interfaces,
2087b9d36b47SEd Tanous         [aResp,
2088e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2089b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
20903a2d0424SChris Cain         if (ec)
20913a2d0424SChris Cain         {
2092002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2093002d39b4SEd Tanous                              << ec;
20943a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
20953a2d0424SChris Cain             messages::internalError(aResp->res);
20963a2d0424SChris Cain             return;
20973a2d0424SChris Cain         }
20983a2d0424SChris Cain         if (subtree.empty())
20993a2d0424SChris Cain         {
21003a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21013a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
21023a2d0424SChris Cain                                        "PowerMode");
21033a2d0424SChris Cain             return;
21043a2d0424SChris Cain         }
21053a2d0424SChris Cain         if (subtree.size() > 1)
21063a2d0424SChris Cain         {
21073a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21083a2d0424SChris Cain             // error
21093a2d0424SChris Cain             BMCWEB_LOG_DEBUG
21103a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
21113a2d0424SChris Cain                 << subtree.size();
21123a2d0424SChris Cain             messages::internalError(aResp->res);
21133a2d0424SChris Cain             return;
21143a2d0424SChris Cain         }
21153a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21163a2d0424SChris Cain         {
21173a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21183a2d0424SChris Cain             messages::internalError(aResp->res);
21193a2d0424SChris Cain             return;
21203a2d0424SChris Cain         }
21213a2d0424SChris Cain         const std::string& path = subtree[0].first;
21223a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21233a2d0424SChris Cain         if (service.empty())
21243a2d0424SChris Cain         {
21253a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21263a2d0424SChris Cain             messages::internalError(aResp->res);
21273a2d0424SChris Cain             return;
21283a2d0424SChris Cain         }
21293a2d0424SChris Cain 
21303a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
21313a2d0424SChris Cain                          << path;
21323a2d0424SChris Cain 
21333a2d0424SChris Cain         // Set the Power Mode property
21343a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
2135*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
21368a592810SEd Tanous             if (ec2)
21373a2d0424SChris Cain             {
21383a2d0424SChris Cain                 messages::internalError(aResp->res);
21393a2d0424SChris Cain                 return;
21403a2d0424SChris Cain             }
21413a2d0424SChris Cain             },
21423a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
21433a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2144168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
2145e99073f5SGeorge Liu         });
21463a2d0424SChris Cain }
21473a2d0424SChris Cain 
21483a2d0424SChris Cain /**
214951709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
215051709ffdSYong Li  *
215151709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
215251709ffdSYong Li  *
215351709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
215451709ffdSYong Li  * translation cannot be done, returns an empty string.
215551709ffdSYong Li  */
215623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
215751709ffdSYong Li {
215851709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
215951709ffdSYong Li     {
216051709ffdSYong Li         return "None";
216151709ffdSYong Li     }
21623174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
216351709ffdSYong Li     {
216451709ffdSYong Li         return "ResetSystem";
216551709ffdSYong Li     }
21663174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
216751709ffdSYong Li     {
216851709ffdSYong Li         return "PowerDown";
216951709ffdSYong Li     }
21703174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
217151709ffdSYong Li     {
217251709ffdSYong Li         return "PowerCycle";
217351709ffdSYong Li     }
217451709ffdSYong Li 
217551709ffdSYong Li     return "";
217651709ffdSYong Li }
217751709ffdSYong Li 
217851709ffdSYong Li /**
2179c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2180c45f0082SYong Li  *
2181c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2182c45f0082SYong Li  *
2183c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2184c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2185c45f0082SYong Li  */
2186c45f0082SYong Li 
218723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2188c45f0082SYong Li {
2189c45f0082SYong Li     if (rfAction == "None")
2190c45f0082SYong Li     {
2191c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2192c45f0082SYong Li     }
21933174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2194c45f0082SYong Li     {
2195c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2196c45f0082SYong Li     }
21973174e4dfSEd Tanous     if (rfAction == "PowerDown")
2198c45f0082SYong Li     {
2199c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2200c45f0082SYong Li     }
22013174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2202c45f0082SYong Li     {
2203c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2204c45f0082SYong Li     }
2205c45f0082SYong Li 
2206c45f0082SYong Li     return "";
2207c45f0082SYong Li }
2208c45f0082SYong Li 
2209c45f0082SYong Li /**
221051709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
221151709ffdSYong Li  *
221251709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
221351709ffdSYong Li  *
221451709ffdSYong Li  * @return None.
221551709ffdSYong Li  */
22168d1b46d7Szhanghch05 inline void
22178d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
221851709ffdSYong Li {
221951709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2220bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2221bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2222bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2223bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2224*5e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
2225b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
222651709ffdSYong Li         if (ec)
222751709ffdSYong Li         {
222851709ffdSYong Li             // watchdog service is stopped
222951709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
223051709ffdSYong Li             return;
223151709ffdSYong Li         }
223251709ffdSYong Li 
223351709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
223451709ffdSYong Li 
223551709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
223651709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
223751709ffdSYong Li 
223851709ffdSYong Li         // watchdog service is running/enabled
223951709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
224051709ffdSYong Li 
2241bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2242bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
224351709ffdSYong Li 
2244bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2245bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2246bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2247bc1d29deSKrzysztof Grobelny 
2248bc1d29deSKrzysztof Grobelny         if (!success)
224951709ffdSYong Li         {
225051709ffdSYong Li             messages::internalError(aResp->res);
2251601af5edSChicago Duan             return;
225251709ffdSYong Li         }
225351709ffdSYong Li 
2254bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
225551709ffdSYong Li         {
2256bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
225751709ffdSYong Li         }
225851709ffdSYong Li 
2259bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2260bc1d29deSKrzysztof Grobelny         {
2261bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
226251709ffdSYong Li             if (action.empty())
226351709ffdSYong Li             {
226451709ffdSYong Li                 messages::internalError(aResp->res);
2265601af5edSChicago Duan                 return;
226651709ffdSYong Li             }
226751709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
226851709ffdSYong Li         }
2269bc1d29deSKrzysztof Grobelny         });
227051709ffdSYong Li }
227151709ffdSYong Li 
227251709ffdSYong Li /**
2273c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2274c45f0082SYong Li  *
2275c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2276c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2277c45f0082SYong Li  *                       RF request.
2278c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2279c45f0082SYong Li  *
2280c45f0082SYong Li  * @return None.
2281c45f0082SYong Li  */
22828d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2283c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2284c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2285c45f0082SYong Li {
2286c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2287c45f0082SYong Li 
2288c45f0082SYong Li     if (wdtTimeOutAction)
2289c45f0082SYong Li     {
2290c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2291c45f0082SYong Li         // check if TimeOut Action is Valid
2292c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2293c45f0082SYong Li         {
2294c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2295c45f0082SYong Li                              << *wdtTimeOutAction;
2296c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2297c45f0082SYong Li                                              "TimeoutAction");
2298c45f0082SYong Li             return;
2299c45f0082SYong Li         }
2300c45f0082SYong Li 
2301c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2302*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2303c45f0082SYong Li             if (ec)
2304c45f0082SYong Li             {
2305c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2306c45f0082SYong Li                 messages::internalError(aResp->res);
2307c45f0082SYong Li                 return;
2308c45f0082SYong Li             }
2309c45f0082SYong Li             },
2310c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2311c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2312c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2313c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2314168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2315c45f0082SYong Li     }
2316c45f0082SYong Li 
2317c45f0082SYong Li     if (wdtEnable)
2318c45f0082SYong Li     {
2319c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2320*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2321c45f0082SYong Li             if (ec)
2322c45f0082SYong Li             {
2323c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2324c45f0082SYong Li                 messages::internalError(aResp->res);
2325c45f0082SYong Li                 return;
2326c45f0082SYong Li             }
2327c45f0082SYong Li             },
2328c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2329c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2330c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2331c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2332168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2333c45f0082SYong Li     }
2334c45f0082SYong Li }
2335c45f0082SYong Li 
233637bbf98cSChris Cain /**
233737bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
233837bbf98cSChris Cain  *
233937bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
234037bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
234137bbf98cSChris Cain  *
234237bbf98cSChris Cain  * @return true if successful
234337bbf98cSChris Cain  */
23441e5b7c88SJiaqing Zhao inline bool
23451e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
23461e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
234737bbf98cSChris Cain {
2348bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2349bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2350bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2351bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2352bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2353bc1d29deSKrzysztof Grobelny 
2354bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2355bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2356bc1d29deSKrzysztof Grobelny         "EnterUtilizationPercent", enterUtilizationPercent,
2357bc1d29deSKrzysztof Grobelny         "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime",
2358bc1d29deSKrzysztof Grobelny         exitDwellTime);
2359bc1d29deSKrzysztof Grobelny 
2360bc1d29deSKrzysztof Grobelny     if (!success)
236137bbf98cSChris Cain     {
236237bbf98cSChris Cain         return false;
236337bbf98cSChris Cain     }
2364bc1d29deSKrzysztof Grobelny 
2365bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
236637bbf98cSChris Cain     {
2367bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
236837bbf98cSChris Cain     }
2369bc1d29deSKrzysztof Grobelny 
2370bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
237137bbf98cSChris Cain     {
2372bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2373bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
237437bbf98cSChris Cain     }
2375bc1d29deSKrzysztof Grobelny 
2376bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2377bc1d29deSKrzysztof Grobelny     {
2378bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
237937bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
238037bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
238137bbf98cSChris Cain                 .count();
238237bbf98cSChris Cain     }
2383bc1d29deSKrzysztof Grobelny 
2384bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
238537bbf98cSChris Cain     {
2386bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2387bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
238837bbf98cSChris Cain     }
2389bc1d29deSKrzysztof Grobelny 
2390bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
239137bbf98cSChris Cain     {
2392bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
239337bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
239437bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
239537bbf98cSChris Cain                 .count();
239637bbf98cSChris Cain     }
239737bbf98cSChris Cain 
239837bbf98cSChris Cain     return true;
239937bbf98cSChris Cain }
240037bbf98cSChris Cain 
240137bbf98cSChris Cain /**
240237bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
240337bbf98cSChris Cain  *
240437bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
240537bbf98cSChris Cain  *
240637bbf98cSChris Cain  * @return None.
240737bbf98cSChris Cain  */
240837bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
240937bbf98cSChris Cain {
241037bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
241137bbf98cSChris Cain 
241237bbf98cSChris Cain     // Get IdlePowerSaver object path:
2413e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2414e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2415e99073f5SGeorge Liu     dbus::utility::getSubTree(
2416e99073f5SGeorge Liu         "/", 0, interfaces,
2417e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2418b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
241937bbf98cSChris Cain         if (ec)
242037bbf98cSChris Cain         {
242137bbf98cSChris Cain             BMCWEB_LOG_DEBUG
242237bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
242337bbf98cSChris Cain                 << ec;
242437bbf98cSChris Cain             messages::internalError(aResp->res);
242537bbf98cSChris Cain             return;
242637bbf98cSChris Cain         }
242737bbf98cSChris Cain         if (subtree.empty())
242837bbf98cSChris Cain         {
242937bbf98cSChris Cain             // This is an optional interface so just return
243037bbf98cSChris Cain             // if there is no instance found
243137bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
243237bbf98cSChris Cain             return;
243337bbf98cSChris Cain         }
243437bbf98cSChris Cain         if (subtree.size() > 1)
243537bbf98cSChris Cain         {
243637bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
243737bbf98cSChris Cain             // is an error
243837bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
243937bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
244037bbf98cSChris Cain                              << subtree.size();
244137bbf98cSChris Cain             messages::internalError(aResp->res);
244237bbf98cSChris Cain             return;
244337bbf98cSChris Cain         }
244437bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
244537bbf98cSChris Cain         {
244637bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
244737bbf98cSChris Cain             messages::internalError(aResp->res);
244837bbf98cSChris Cain             return;
244937bbf98cSChris Cain         }
245037bbf98cSChris Cain         const std::string& path = subtree[0].first;
245137bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
245237bbf98cSChris Cain         if (service.empty())
245337bbf98cSChris Cain         {
2454002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
245537bbf98cSChris Cain             messages::internalError(aResp->res);
245637bbf98cSChris Cain             return;
245737bbf98cSChris Cain         }
245837bbf98cSChris Cain 
245937bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2460bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2461bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2462bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2463*5e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
24641e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
24658a592810SEd Tanous             if (ec2)
246637bbf98cSChris Cain             {
246737bbf98cSChris Cain                 BMCWEB_LOG_ERROR
24688a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
246937bbf98cSChris Cain                 messages::internalError(aResp->res);
247037bbf98cSChris Cain                 return;
247137bbf98cSChris Cain             }
247237bbf98cSChris Cain 
2473e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
247437bbf98cSChris Cain             {
247537bbf98cSChris Cain                 messages::internalError(aResp->res);
247637bbf98cSChris Cain                 return;
247737bbf98cSChris Cain             }
2478bc1d29deSKrzysztof Grobelny             });
2479e99073f5SGeorge Liu         });
248037bbf98cSChris Cain 
248137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
248237bbf98cSChris Cain }
248337bbf98cSChris Cain 
248437bbf98cSChris Cain /**
248537bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
248637bbf98cSChris Cain  *
248737bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
248837bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
248937bbf98cSChris Cain  *                       RF request.
249037bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
249137bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
249237bbf98cSChris Cain  * before entering idle state.
249337bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
249437bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
249537bbf98cSChris Cain  * before exiting idle state
249637bbf98cSChris Cain  *
249737bbf98cSChris Cain  * @return None.
249837bbf98cSChris Cain  */
249937bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
250037bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
250137bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
250237bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
250337bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
250437bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
250537bbf98cSChris Cain {
250637bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
250737bbf98cSChris Cain 
250837bbf98cSChris Cain     // Get IdlePowerSaver object path:
2509e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2510e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2511e99073f5SGeorge Liu     dbus::utility::getSubTree(
2512e99073f5SGeorge Liu         "/", 0, interfaces,
251337bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2514e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2515b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
251637bbf98cSChris Cain         if (ec)
251737bbf98cSChris Cain         {
251837bbf98cSChris Cain             BMCWEB_LOG_DEBUG
251937bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
252037bbf98cSChris Cain                 << ec;
252137bbf98cSChris Cain             messages::internalError(aResp->res);
252237bbf98cSChris Cain             return;
252337bbf98cSChris Cain         }
252437bbf98cSChris Cain         if (subtree.empty())
252537bbf98cSChris Cain         {
252637bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
252737bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
252837bbf98cSChris Cain                                        "IdlePowerSaver");
252937bbf98cSChris Cain             return;
253037bbf98cSChris Cain         }
253137bbf98cSChris Cain         if (subtree.size() > 1)
253237bbf98cSChris Cain         {
253337bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
253437bbf98cSChris Cain             // is an error
25350fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
25360fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
253737bbf98cSChris Cain                 << subtree.size();
253837bbf98cSChris Cain             messages::internalError(aResp->res);
253937bbf98cSChris Cain             return;
254037bbf98cSChris Cain         }
254137bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
254237bbf98cSChris Cain         {
254337bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
254437bbf98cSChris Cain             messages::internalError(aResp->res);
254537bbf98cSChris Cain             return;
254637bbf98cSChris Cain         }
254737bbf98cSChris Cain         const std::string& path = subtree[0].first;
254837bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
254937bbf98cSChris Cain         if (service.empty())
255037bbf98cSChris Cain         {
2551002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
255237bbf98cSChris Cain             messages::internalError(aResp->res);
255337bbf98cSChris Cain             return;
255437bbf98cSChris Cain         }
255537bbf98cSChris Cain 
255637bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
255737bbf98cSChris Cain         // need to be updated
255837bbf98cSChris Cain 
255937bbf98cSChris Cain         if (ipsEnable)
256037bbf98cSChris Cain         {
256137bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2562*5e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
25638a592810SEd Tanous                 if (ec2)
256437bbf98cSChris Cain                 {
25658a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
256637bbf98cSChris Cain                     messages::internalError(aResp->res);
256737bbf98cSChris Cain                     return;
256837bbf98cSChris Cain                 }
256937bbf98cSChris Cain                 },
257037bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2571002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2572002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
257337bbf98cSChris Cain         }
257437bbf98cSChris Cain         if (ipsEnterUtil)
257537bbf98cSChris Cain         {
257637bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2577*5e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
25788a592810SEd Tanous                 if (ec2)
257937bbf98cSChris Cain                 {
25808a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
258137bbf98cSChris Cain                     messages::internalError(aResp->res);
258237bbf98cSChris Cain                     return;
258337bbf98cSChris Cain                 }
258437bbf98cSChris Cain                 },
258537bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
258637bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
258737bbf98cSChris Cain                 "EnterUtilizationPercent",
2588168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
258937bbf98cSChris Cain         }
259037bbf98cSChris Cain         if (ipsEnterTime)
259137bbf98cSChris Cain         {
259237bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
259337bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
259437bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2595*5e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
25968a592810SEd Tanous                 if (ec2)
259737bbf98cSChris Cain                 {
25988a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
259937bbf98cSChris Cain                     messages::internalError(aResp->res);
260037bbf98cSChris Cain                     return;
260137bbf98cSChris Cain                 }
260237bbf98cSChris Cain                 },
260337bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
260437bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2605168e20c1SEd Tanous                 "EnterDwellTime",
2606168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
260737bbf98cSChris Cain         }
260837bbf98cSChris Cain         if (ipsExitUtil)
260937bbf98cSChris Cain         {
261037bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2611*5e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26128a592810SEd Tanous                 if (ec2)
261337bbf98cSChris Cain                 {
26148a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
261537bbf98cSChris Cain                     messages::internalError(aResp->res);
261637bbf98cSChris Cain                     return;
261737bbf98cSChris Cain                 }
261837bbf98cSChris Cain                 },
261937bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
262037bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
262137bbf98cSChris Cain                 "ExitUtilizationPercent",
2622168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
262337bbf98cSChris Cain         }
262437bbf98cSChris Cain         if (ipsExitTime)
262537bbf98cSChris Cain         {
262637bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
262737bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
262837bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2629*5e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26308a592810SEd Tanous                 if (ec2)
263137bbf98cSChris Cain                 {
26328a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
263337bbf98cSChris Cain                     messages::internalError(aResp->res);
263437bbf98cSChris Cain                     return;
263537bbf98cSChris Cain                 }
263637bbf98cSChris Cain                 },
263737bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
263837bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2639168e20c1SEd Tanous                 "ExitDwellTime",
2640168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
264137bbf98cSChris Cain         }
2642e99073f5SGeorge Liu         });
264337bbf98cSChris Cain 
264437bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
264537bbf98cSChris Cain }
264637bbf98cSChris Cain 
2647dd60b9edSEd Tanous inline void handleComputerSystemHead(
2648dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2649dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2650dd60b9edSEd Tanous {
2651dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2652dd60b9edSEd Tanous     {
2653dd60b9edSEd Tanous         return;
2654dd60b9edSEd Tanous     }
2655dd60b9edSEd Tanous     asyncResp->res.addHeader(
2656dd60b9edSEd Tanous         boost::beast::http::field::link,
2657dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2658dd60b9edSEd Tanous }
2659dd60b9edSEd Tanous 
2660c45f0082SYong Li /**
2661c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2662c5b2abe0SLewanczyk, Dawid  * Schema
2663c5b2abe0SLewanczyk, Dawid  */
26647e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
26651abe55efSEd Tanous {
26667e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2667dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2668dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2669dd60b9edSEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
2670dd60b9edSEd Tanous 
2671dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2672ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
26737e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2674f4c99e70SEd Tanous             [&app](const crow::Request& req,
26757e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
26763ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2677f4c99e70SEd Tanous         {
2678f4c99e70SEd Tanous             return;
2679f4c99e70SEd Tanous         }
2680dd60b9edSEd Tanous 
2681dd60b9edSEd Tanous         asyncResp->res.addHeader(
2682dd60b9edSEd Tanous             boost::beast::http::field::link,
2683dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
26848d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
26850f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
26868d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
26878d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2688462023adSSunitha Harish 
26891e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2690002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
26911e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2692002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2693*5e7e2dc5SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
26941e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2695002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
26962c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2697002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
26981476687dSEd Tanous 
26991476687dSEd Tanous             nlohmann::json::object_t system;
27001476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
27011476687dSEd Tanous             ifaceArray.push_back(std::move(system));
270294bda602STim Lee             count = ifaceArray.size();
27038a592810SEd Tanous             if (!ec2)
2704462023adSSunitha Harish             {
2705462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
27061476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2707002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
27081476687dSEd Tanous                 ifaceArray.push_back(std::move(hypervisor));
27092c70f800SEd Tanous                 count = ifaceArray.size();
2710cb13a392SEd Tanous             }
27111e1e598dSJonathan Doman             });
27127e860f15SJohn Edward Broadbent         });
2713c5b2abe0SLewanczyk, Dawid }
27147e860f15SJohn Edward Broadbent 
27157e860f15SJohn Edward Broadbent /**
27167e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
27177e860f15SJohn Edward Broadbent  */
27184f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27197e860f15SJohn Edward Broadbent {
27207e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
27217e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
27227e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
27237e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
27247e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
27257e860f15SJohn Edward Broadbent 
27267e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
2727*5e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
27287e860f15SJohn Edward Broadbent         if (ec)
27297e860f15SJohn Edward Broadbent         {
27307e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
27317e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
27327e860f15SJohn Edward Broadbent             return;
27337e860f15SJohn Edward Broadbent         }
27347e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
27357e860f15SJohn Edward Broadbent         },
27367e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
27377e860f15SJohn Edward Broadbent }
2738c5b2abe0SLewanczyk, Dawid 
2739c5b2abe0SLewanczyk, Dawid /**
2740cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2741cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2742cc340dd9SEd Tanous  */
27437e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2744cc340dd9SEd Tanous {
2745cc340dd9SEd Tanous     /**
2746cc340dd9SEd Tanous      * Function handles POST method request.
2747cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2748cc340dd9SEd Tanous      */
27497e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
27507e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2751ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2752002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2753002d39b4SEd Tanous             [&app](const crow::Request& req,
27547e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27553ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
275645ca1b86SEd Tanous         {
275745ca1b86SEd Tanous             return;
275845ca1b86SEd Tanous         }
27599712f8acSEd Tanous         std::string resetType;
276015ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
27617e860f15SJohn Edward Broadbent                                        resetType))
2762cc340dd9SEd Tanous         {
2763cc340dd9SEd Tanous             return;
2764cc340dd9SEd Tanous         }
2765cc340dd9SEd Tanous 
2766d22c8396SJason M. Bills         // Get the command and host vs. chassis
2767cc340dd9SEd Tanous         std::string command;
2768543f4400SEd Tanous         bool hostCommand = true;
2769d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2770cc340dd9SEd Tanous         {
2771cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2772d22c8396SJason M. Bills             hostCommand = true;
2773d22c8396SJason M. Bills         }
2774d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2775d22c8396SJason M. Bills         {
2776d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2777d22c8396SJason M. Bills             hostCommand = false;
2778d22c8396SJason M. Bills         }
2779d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2780d22c8396SJason M. Bills         {
278186a0851aSJason M. Bills             command =
278286a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
278386a0851aSJason M. Bills             hostCommand = true;
2784cc340dd9SEd Tanous         }
27859712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2786cc340dd9SEd Tanous         {
2787cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2788d22c8396SJason M. Bills             hostCommand = true;
2789cc340dd9SEd Tanous         }
27909712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2791cc340dd9SEd Tanous         {
27920fda0f12SGeorge Liu             command =
27930fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2794d22c8396SJason M. Bills             hostCommand = true;
2795d22c8396SJason M. Bills         }
2796d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2797d22c8396SJason M. Bills         {
279886a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
279986a0851aSJason M. Bills             hostCommand = true;
2800cc340dd9SEd Tanous         }
2801bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2802bfd5b826SLakshminarayana R. Kammath         {
2803bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2804bfd5b826SLakshminarayana R. Kammath             return;
2805bfd5b826SLakshminarayana R. Kammath         }
2806cc340dd9SEd Tanous         else
2807cc340dd9SEd Tanous         {
28088d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
28098d1b46d7Szhanghch05                                              resetType);
2810cc340dd9SEd Tanous             return;
2811cc340dd9SEd Tanous         }
2812cc340dd9SEd Tanous 
2813d22c8396SJason M. Bills         if (hostCommand)
2814d22c8396SJason M. Bills         {
2815cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
2816*5e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2817cc340dd9SEd Tanous                 if (ec)
2818cc340dd9SEd Tanous                 {
2819cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2820002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2821d22c8396SJason M. Bills                     {
2822d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2823d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2824d22c8396SJason M. Bills                     }
2825d22c8396SJason M. Bills                     else
2826d22c8396SJason M. Bills                     {
2827f12894f8SJason M. Bills                         messages::internalError(asyncResp->res);
2828d22c8396SJason M. Bills                     }
2829cc340dd9SEd Tanous                     return;
2830cc340dd9SEd Tanous                 }
2831f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2832cc340dd9SEd Tanous                 },
2833cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2834cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2835cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
28369712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2837168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2838cc340dd9SEd Tanous         }
2839d22c8396SJason M. Bills         else
2840d22c8396SJason M. Bills         {
2841d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
2842*5e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2843d22c8396SJason M. Bills                 if (ec)
2844d22c8396SJason M. Bills                 {
2845d22c8396SJason M. Bills                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2846002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2847d22c8396SJason M. Bills                     {
2848d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2849d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2850d22c8396SJason M. Bills                     }
2851d22c8396SJason M. Bills                     else
2852d22c8396SJason M. Bills                     {
2853d22c8396SJason M. Bills                         messages::internalError(asyncResp->res);
2854d22c8396SJason M. Bills                     }
2855d22c8396SJason M. Bills                     return;
2856d22c8396SJason M. Bills                 }
2857d22c8396SJason M. Bills                 messages::success(asyncResp->res);
2858d22c8396SJason M. Bills                 },
2859d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
2860d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
2861d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
2862002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2863168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2864d22c8396SJason M. Bills         }
28657e860f15SJohn Edward Broadbent         });
2866d22c8396SJason M. Bills }
2867cc340dd9SEd Tanous 
286838c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead(
2869dd60b9edSEd Tanous     App& app, const crow::Request& req,
2870dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2871dd60b9edSEd Tanous {
2872dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2873dd60b9edSEd Tanous     {
2874dd60b9edSEd Tanous         return;
2875dd60b9edSEd Tanous     }
2876dd60b9edSEd Tanous 
2877dd60b9edSEd Tanous     asyncResp->res.addHeader(
2878dd60b9edSEd Tanous         boost::beast::http::field::link,
2879dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2880dd60b9edSEd Tanous }
2881dd60b9edSEd Tanous 
2882cc340dd9SEd Tanous /**
28836617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2884c5b2abe0SLewanczyk, Dawid  */
28857e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
28861abe55efSEd Tanous {
2887c5b2abe0SLewanczyk, Dawid 
2888dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2889dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystem)
2890dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2891dd60b9edSEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
2892c5b2abe0SLewanczyk, Dawid     /**
2893c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2894c5b2abe0SLewanczyk, Dawid      */
289522d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
2896ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
2897002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
2898002d39b4SEd Tanous             [&app](const crow::Request& req,
289922d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
290022d268cbSEd Tanous                    const std::string& systemName) {
29013ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
290245ca1b86SEd Tanous         {
290345ca1b86SEd Tanous             return;
290445ca1b86SEd Tanous         }
290522d268cbSEd Tanous         if (systemName != "system")
290622d268cbSEd Tanous         {
290722d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
290822d268cbSEd Tanous                                        systemName);
290922d268cbSEd Tanous             return;
291022d268cbSEd Tanous         }
2911dd60b9edSEd Tanous         asyncResp->res.addHeader(
2912dd60b9edSEd Tanous             boost::beast::http::field::link,
2913dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
29148d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
291537bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
29168d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
29178d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
29188d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
29198d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
29208d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
29218d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
29228d1b46d7Szhanghch05             "Disabled";
29238d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
29248d1b46d7Szhanghch05             uint64_t(0);
29258d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
29268d1b46d7Szhanghch05             "Disabled";
2927002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
292804a258f4SEd Tanous 
29291476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
29301476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
29311476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
29321476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
29331476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
29341476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
29353179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
29363179105bSSunny Srivastava             "/redfish/v1/Systems/system/FabricAdapters";
2937029573d4SEd Tanous 
2938002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
29391476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
29401476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
29411476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
29421476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
2943c5b2abe0SLewanczyk, Dawid 
29441476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
29451476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
29461476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
29471476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
2948c4bf6374SJason M. Bills 
29491476687dSEd Tanous         nlohmann::json::array_t managedBy;
29501476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
29511476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
2952002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
29531476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
29541476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
29550e8ac5e7SGunnar Mills 
29560e8ac5e7SGunnar Mills         // Fill in SerialConsole info
2957002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
2958002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
2959002d39b4SEd Tanous             true;
29601476687dSEd Tanous 
29610e8ac5e7SGunnar Mills         // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
29621476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
29631476687dSEd Tanous             true;
29641476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
29651476687dSEd Tanous         asyncResp->res
29661476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
29671476687dSEd Tanous             "Press ~. to exit console";
29680e8ac5e7SGunnar Mills 
29690e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
29700e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
2971002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
2972002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
2973002d39b4SEd Tanous             4;
2974613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
2975613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
29761476687dSEd Tanous 
29770e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
29787a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
2979b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
29802ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
2981e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
2982e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
2983b49ac873SJames Feist 
2984b49ac873SJames Feist         auto health = std::make_shared<HealthPopulate>(asyncResp);
29857a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
29867a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
29877a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
2988914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
2989b49ac873SJames Feist             if (ec)
2990b49ac873SJames Feist             {
2991b49ac873SJames Feist                 // no inventory
2992b49ac873SJames Feist                 return;
2993b49ac873SJames Feist             }
2994b49ac873SJames Feist 
2995914e2d5dSEd Tanous             health->inventory = resp;
29967a1dbc48SGeorge Liu             });
2997b49ac873SJames Feist 
2998b49ac873SJames Feist         health->populate();
2999b49ac873SJames Feist 
3000002d39b4SEd Tanous         getMainChassisId(asyncResp,
3001002d39b4SEd Tanous                          [](const std::string& chassisId,
30028d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3003b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3004b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3005eddfc437SWilly Tu             chassis["@odata.id"] = crow::utility::urlFromPieces(
3006eddfc437SWilly Tu                 "redfish", "v1", "Chassis", chassisId);
3007002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3008c5d03ff4SJennifer Lee         });
3009a3002228SAppaRao Puli 
30109f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
30119f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3012a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
30135bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
30146c34de48SEd Tanous         getHostState(asyncResp);
3015491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
3016978b8803SAndrew Geissler         getBootProgress(asyncResp);
3017b6d5d45cSHieu Huynh         getBootProgressLastStateTime(asyncResp);
3018adbe192aSJason M. Bills         getPCIeDeviceList(asyncResp, "PCIeDevices");
301951709ffdSYong Li         getHostWatchdogTimer(asyncResp);
3020c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
30216bd5a8d2SGunnar Mills         getAutomaticRetry(asyncResp);
3022c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
3023a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3024a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
3025a6349918SAppaRao Puli #endif
30261981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
30273a2d0424SChris Cain         getPowerMode(asyncResp);
302837bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
30297e860f15SJohn Edward Broadbent         });
3030550a6bf8SJiaqing Zhao 
303122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3032ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
30337e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
303445ca1b86SEd Tanous             [&app](const crow::Request& req,
303522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
303622d268cbSEd Tanous                    const std::string& systemName) {
30373ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
303845ca1b86SEd Tanous         {
303945ca1b86SEd Tanous             return;
304045ca1b86SEd Tanous         }
304122d268cbSEd Tanous         if (systemName != "system")
304222d268cbSEd Tanous         {
304322d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
304422d268cbSEd Tanous                                        systemName);
304522d268cbSEd Tanous             return;
304622d268cbSEd Tanous         }
304722d268cbSEd Tanous 
3048dd60b9edSEd Tanous         asyncResp->res.addHeader(
3049dd60b9edSEd Tanous             boost::beast::http::field::link,
3050dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3051dd60b9edSEd Tanous 
30529f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
3053cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
305498e386ecSGunnar Mills         std::optional<std::string> assetTag;
3055c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
30563a2d0424SChris Cain         std::optional<std::string> powerMode;
3057550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
3058550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
3059550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
3060550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
3061550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
3062550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
3063550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
3064550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
3065550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
3066550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
3067550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
3068550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
3069550a6bf8SJiaqing Zhao 
3070550a6bf8SJiaqing Zhao         // clang-format off
307115ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3072550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3073550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
30747e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3075550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3076550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3077550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3078550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3079550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3080550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3081550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3082550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3083550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3084550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3085550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3086550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3087550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3088550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3089550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
30906617338dSEd Tanous                 {
30916617338dSEd Tanous                     return;
30926617338dSEd Tanous                 }
3093550a6bf8SJiaqing Zhao         // clang-format on
3094491d8ee7SSantosh Puranik 
30958d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3096c45f0082SYong Li 
309798e386ecSGunnar Mills         if (assetTag)
309898e386ecSGunnar Mills         {
309998e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
310098e386ecSGunnar Mills         }
310198e386ecSGunnar Mills 
3102550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3103c45f0082SYong Li         {
3104f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3105c45f0082SYong Li         }
3106c45f0082SYong Li 
3107cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
310869f35306SGunnar Mills         {
3109002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3110491d8ee7SSantosh Puranik         }
3111550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
311269f35306SGunnar Mills         {
3113550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
311469f35306SGunnar Mills         }
3115ac7e1e0bSAli Ahmed 
3116550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3117ac7e1e0bSAli Ahmed         {
3118550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3119550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
312069f35306SGunnar Mills         }
3121265c1602SJohnathan Mantey 
31229f8bfa7cSGunnar Mills         if (locationIndicatorActive)
31239f8bfa7cSGunnar Mills         {
3124002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
31259f8bfa7cSGunnar Mills         }
31269f8bfa7cSGunnar Mills 
31277e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
31287e860f15SJohn Edward Broadbent         // passed
31299712f8acSEd Tanous         if (indicatorLed)
31306617338dSEd Tanous         {
3131f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3132002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3133d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3134d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
31356617338dSEd Tanous         }
3136c6a620f2SGeorge Liu 
3137c6a620f2SGeorge Liu         if (powerRestorePolicy)
3138c6a620f2SGeorge Liu         {
31394e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3140c6a620f2SGeorge Liu         }
31413a2d0424SChris Cain 
31423a2d0424SChris Cain         if (powerMode)
31433a2d0424SChris Cain         {
31443a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
31453a2d0424SChris Cain         }
314637bbf98cSChris Cain 
3147550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3148550a6bf8SJiaqing Zhao             ipsExitTime)
314937bbf98cSChris Cain         {
3150002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3151002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
315237bbf98cSChris Cain         }
31537e860f15SJohn Edward Broadbent         });
3154c5b2abe0SLewanczyk, Dawid }
31551cb1a9e6SAppaRao Puli 
315638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3157dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
3158dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3159dd60b9edSEd Tanous {
3160dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3161dd60b9edSEd Tanous     {
3162dd60b9edSEd Tanous         return;
3163dd60b9edSEd Tanous     }
3164dd60b9edSEd Tanous     asyncResp->res.addHeader(
3165dd60b9edSEd Tanous         boost::beast::http::field::link,
3166dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3167dd60b9edSEd Tanous }
3168dd60b9edSEd Tanous 
31691cb1a9e6SAppaRao Puli /**
31701cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
31711cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
31721cb1a9e6SAppaRao Puli  */
31737e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
31741cb1a9e6SAppaRao Puli {
3175dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3176dd60b9edSEd Tanous         .privileges(redfish::privileges::headActionInfo)
3177dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3178dd60b9edSEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
31791cb1a9e6SAppaRao Puli     /**
31801cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
31811cb1a9e6SAppaRao Puli      */
318222d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3183ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
31847e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
318545ca1b86SEd Tanous             [&app](const crow::Request& req,
318622d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
318722d268cbSEd Tanous                    const std::string& systemName) {
31883ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
318945ca1b86SEd Tanous         {
319045ca1b86SEd Tanous             return;
319145ca1b86SEd Tanous         }
319222d268cbSEd Tanous         if (systemName != "system")
319322d268cbSEd Tanous         {
319422d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
319522d268cbSEd Tanous                                        systemName);
319622d268cbSEd Tanous             return;
319722d268cbSEd Tanous         }
319822d268cbSEd Tanous 
3199dd60b9edSEd Tanous         asyncResp->res.addHeader(
3200dd60b9edSEd Tanous             boost::beast::http::field::link,
3201dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
32021476687dSEd Tanous 
32031476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
32041476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
32051476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
32061476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
32071476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
32081476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
32093215e700SNan Zhou 
32103215e700SNan Zhou         nlohmann::json::array_t parameters;
32113215e700SNan Zhou         nlohmann::json::object_t parameter;
32123215e700SNan Zhou 
32133215e700SNan Zhou         parameter["Name"] = "ResetType";
32143215e700SNan Zhou         parameter["Required"] = true;
32153215e700SNan Zhou         parameter["DataType"] = "String";
32163215e700SNan Zhou         nlohmann::json::array_t allowableValues;
32173215e700SNan Zhou         allowableValues.emplace_back("On");
32183215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
32193215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
32203215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
32213215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
32223215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
32233215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
32243215e700SNan Zhou         allowableValues.emplace_back("Nmi");
32253215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
32263215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
32273215e700SNan Zhou 
32283215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
32297e860f15SJohn Edward Broadbent         });
32301cb1a9e6SAppaRao Puli }
3231c5b2abe0SLewanczyk, Dawid } // namespace redfish
3232