xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 38c8a6f28b69ed4a08b8d20056db37dac071c05c)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
181e1e598dSJonathan Doman #include "dbus_singleton.hpp"
19b49ac873SJames Feist #include "health.hpp"
201c8fba97SJames Feist #include "led.hpp"
21f5c9f8bdSJason M. Bills #include "pcie.hpp"
22f4c99e70SEd Tanous #include "query.hpp"
23c5d03ff4SJennifer Lee #include "redfish_util.hpp"
242b82937eSEd Tanous #include "utils/time_utils.hpp"
25c5d03ff4SJennifer Lee 
267e860f15SJohn Edward Broadbent #include <app.hpp>
279712f8acSEd Tanous #include <boost/container/flat_map.hpp>
28168e20c1SEd Tanous #include <dbus_utility.hpp>
29ed398213SEd Tanous #include <registries/privilege_registry.hpp>
301e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
31bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
32bc1d29deSKrzysztof Grobelny #include <utils/dbus_utils.hpp>
33c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
34eee0013eSWilly Tu #include <utils/sw_utils.hpp>
351214b7e7SGunnar Mills 
36abf2add6SEd Tanous #include <variant>
37c5b2abe0SLewanczyk, Dawid 
381abe55efSEd Tanous namespace redfish
391abe55efSEd Tanous {
40c5b2abe0SLewanczyk, Dawid 
419d3ae10eSAlpana Kumari /**
429d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
439d3ae10eSAlpana Kumari  *
449d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
459d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
469d3ae10eSAlpana Kumari  *
479d3ae10eSAlpana Kumari  * @return None.
489d3ae10eSAlpana Kumari  */
498d1b46d7Szhanghch05 inline void
508d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
511e1e598dSJonathan Doman                          bool isDimmFunctional)
529d3ae10eSAlpana Kumari {
531e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
549d3ae10eSAlpana Kumari 
559d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
569d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
579d3ae10eSAlpana Kumari     // ENABLED.
5802cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
599d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
609d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
619d3ae10eSAlpana Kumari     {
62e05aec50SEd Tanous         if (isDimmFunctional)
639d3ae10eSAlpana Kumari         {
649d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
659d3ae10eSAlpana Kumari                 "Enabled";
669d3ae10eSAlpana Kumari         }
679d3ae10eSAlpana Kumari     }
689d3ae10eSAlpana Kumari }
699d3ae10eSAlpana Kumari 
7057e8c9beSAlpana Kumari /*
7157e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
7257e8c9beSAlpana Kumari  *
7357e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
7457e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
7557e8c9beSAlpana Kumari  *
7657e8c9beSAlpana Kumari  * @return None.
7757e8c9beSAlpana Kumari  */
781e1e598dSJonathan Doman inline void
791e1e598dSJonathan Doman     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
801e1e598dSJonathan Doman                            bool isCpuPresent)
8157e8c9beSAlpana Kumari {
821e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
8357e8c9beSAlpana Kumari 
8455f79e6fSEd Tanous     if (isCpuPresent)
8557e8c9beSAlpana Kumari     {
86b4b9595aSJames Feist         nlohmann::json& procCount =
87b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
8855f79e6fSEd Tanous         auto* procCountPtr =
89b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
90b4b9595aSJames Feist         if (procCountPtr != nullptr)
91b4b9595aSJames Feist         {
92b4b9595aSJames Feist             // shouldn't be possible to be nullptr
93b4b9595aSJames Feist             *procCountPtr += 1;
9457e8c9beSAlpana Kumari         }
95b4b9595aSJames Feist     }
9657e8c9beSAlpana Kumari }
9757e8c9beSAlpana Kumari 
9857e8c9beSAlpana Kumari /*
9957e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
10057e8c9beSAlpana Kumari  *        CPU Functional State
10157e8c9beSAlpana Kumari  *
10257e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
10357e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
10457e8c9beSAlpana Kumari  *
10557e8c9beSAlpana Kumari  * @return None.
10657e8c9beSAlpana Kumari  */
1071e1e598dSJonathan Doman inline void
1081e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1091e1e598dSJonathan Doman                              bool isCpuFunctional)
11057e8c9beSAlpana Kumari {
1111e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
11257e8c9beSAlpana Kumari 
11302cad96eSEd Tanous     const nlohmann::json& prevProcState =
11457e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
11557e8c9beSAlpana Kumari 
11657e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
11757e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
11857e8c9beSAlpana Kumari     // Functional.
11957e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
12057e8c9beSAlpana Kumari     {
121e05aec50SEd Tanous         if (isCpuFunctional)
12257e8c9beSAlpana Kumari         {
12357e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
12457e8c9beSAlpana Kumari                 "Enabled";
12557e8c9beSAlpana Kumari         }
12657e8c9beSAlpana Kumari     }
12757e8c9beSAlpana Kumari }
12857e8c9beSAlpana Kumari 
129382d6475SAli Ahmed inline void getProcessorProperties(
130382d6475SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
131382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
132382d6475SAli Ahmed         properties)
13303fbed92SAli Ahmed {
13403fbed92SAli Ahmed 
13503fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
13603fbed92SAli Ahmed 
13703fbed92SAli Ahmed     // TODO: Get Model
13803fbed92SAli Ahmed 
139bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
14003fbed92SAli Ahmed 
141bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
142bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
14303fbed92SAli Ahmed 
144bc1d29deSKrzysztof Grobelny     if (!success)
14503fbed92SAli Ahmed     {
14603fbed92SAli Ahmed         messages::internalError(aResp->res);
14703fbed92SAli Ahmed         return;
14803fbed92SAli Ahmed     }
14903fbed92SAli Ahmed 
150bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
15103fbed92SAli Ahmed     {
152bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
153bc1d29deSKrzysztof Grobelny             aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
154bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
155bc1d29deSKrzysztof Grobelny 
156bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
157bc1d29deSKrzysztof Grobelny         {
158bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
15903fbed92SAli Ahmed         }
16003fbed92SAli Ahmed         else
16103fbed92SAli Ahmed         {
162bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
16303fbed92SAli Ahmed         }
16403fbed92SAli Ahmed     }
16503fbed92SAli Ahmed }
16603fbed92SAli Ahmed 
16703fbed92SAli Ahmed /*
16803fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
16903fbed92SAli Ahmed  *
17003fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
17103fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
17203fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
17303fbed92SAli Ahmed  *
17403fbed92SAli Ahmed  * @return None.
17503fbed92SAli Ahmed  */
17603fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
17703fbed92SAli Ahmed                                 const std::string& service,
17803fbed92SAli Ahmed                                 const std::string& path)
17903fbed92SAli Ahmed {
18003fbed92SAli Ahmed 
181382d6475SAli Ahmed     auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
182382d6475SAli Ahmed                                        const bool cpuPresenceCheck) {
183382d6475SAli Ahmed         if (ec3)
184382d6475SAli Ahmed         {
185382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
186382d6475SAli Ahmed             return;
187382d6475SAli Ahmed         }
188382d6475SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
189382d6475SAli Ahmed     };
190382d6475SAli Ahmed 
191382d6475SAli Ahmed     auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
192382d6475SAli Ahmed                                          const bool cpuFunctionalCheck) {
193382d6475SAli Ahmed         if (ec3)
194382d6475SAli Ahmed         {
195382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
196382d6475SAli Ahmed             return;
197382d6475SAli Ahmed         }
198382d6475SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
199382d6475SAli Ahmed     };
200382d6475SAli Ahmed 
201382d6475SAli Ahmed     // Get the Presence of CPU
202382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
203382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
204382d6475SAli Ahmed         "xyz.openbmc_project.Inventory.Item", "Present",
205382d6475SAli Ahmed         std::move(getCpuPresenceState));
206382d6475SAli Ahmed 
207382d6475SAli Ahmed     // Get the Functional State
208382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
209382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
210382d6475SAli Ahmed         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
211382d6475SAli Ahmed         std::move(getCpuFunctionalState));
212382d6475SAli Ahmed 
213bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
214bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
215bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
21603fbed92SAli Ahmed         [aResp, service,
21703fbed92SAli Ahmed          path](const boost::system::error_code ec2,
218b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
21903fbed92SAli Ahmed         if (ec2)
22003fbed92SAli Ahmed         {
22103fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
22203fbed92SAli Ahmed             messages::internalError(aResp->res);
22303fbed92SAli Ahmed             return;
22403fbed92SAli Ahmed         }
225382d6475SAli Ahmed         getProcessorProperties(aResp, properties);
226bc1d29deSKrzysztof Grobelny         });
22703fbed92SAli Ahmed }
22803fbed92SAli Ahmed 
22957e8c9beSAlpana Kumari /*
230c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
231c5b2abe0SLewanczyk, Dawid  *
232c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2338f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
234c5b2abe0SLewanczyk, Dawid  *
235c5b2abe0SLewanczyk, Dawid  * @return None.
236c5b2abe0SLewanczyk, Dawid  */
237b5a76932SEd Tanous inline void
2388d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
239b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2401abe55efSEd Tanous {
24155c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
2429d3ae10eSAlpana Kumari 
24355c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
244b9d36b47SEd Tanous         [aResp,
245b9d36b47SEd Tanous          systemHealth](const boost::system::error_code ec,
246b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
2471abe55efSEd Tanous         if (ec)
2481abe55efSEd Tanous         {
24955c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
250f12894f8SJason M. Bills             messages::internalError(aResp->res);
251c5b2abe0SLewanczyk, Dawid             return;
252c5b2abe0SLewanczyk, Dawid         }
253c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
254002d39b4SEd Tanous         for (const std::pair<
255002d39b4SEd Tanous                  std::string,
256002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
2571214b7e7SGunnar Mills                  object : subtree)
2581abe55efSEd Tanous         {
259c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
26055c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
261002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
2621214b7e7SGunnar Mills                 connectionNames = object.second;
26326f6976fSEd Tanous             if (connectionNames.empty())
2641abe55efSEd Tanous             {
265c5b2abe0SLewanczyk, Dawid                 continue;
266c5b2abe0SLewanczyk, Dawid             }
267029573d4SEd Tanous 
2685bc2dc8eSJames Feist             auto memoryHealth = std::make_shared<HealthPopulate>(
269dfababfcSNan Zhou                 aResp, "/MemorySummary/Status"_json_pointer);
2705bc2dc8eSJames Feist 
2715bc2dc8eSJames Feist             auto cpuHealth = std::make_shared<HealthPopulate>(
272dfababfcSNan Zhou                 aResp, "/ProcessorSummary/Status"_json_pointer);
2735bc2dc8eSJames Feist 
2745bc2dc8eSJames Feist             systemHealth->children.emplace_back(memoryHealth);
2755bc2dc8eSJames Feist             systemHealth->children.emplace_back(cpuHealth);
2765bc2dc8eSJames Feist 
2776c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
2786c34de48SEd Tanous             // BiosVer
27904a258f4SEd Tanous             for (const auto& connection : connectionNames)
2801abe55efSEd Tanous             {
28104a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
2821abe55efSEd Tanous                 {
28304a258f4SEd Tanous                     if (interfaceName ==
28404a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
2851abe55efSEd Tanous                     {
2861abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
28704a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
2889d3ae10eSAlpana Kumari 
289bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
290bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
291bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Inventory.Item.Dimm",
2929d3ae10eSAlpana Kumari                             [aResp, service{connection.first},
293f23b7296SEd Tanous                              path](const boost::system::error_code ec2,
294b9d36b47SEd Tanous                                    const dbus::utility::DBusPropertiesMap&
2951214b7e7SGunnar Mills                                        properties) {
296cb13a392SEd Tanous                             if (ec2)
2971abe55efSEd Tanous                             {
298002d39b4SEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error "
299002d39b4SEd Tanous                                                  << ec2;
300f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
301c5b2abe0SLewanczyk, Dawid                                 return;
302c5b2abe0SLewanczyk, Dawid                             }
303002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
304c5b2abe0SLewanczyk, Dawid                                              << " Dimm properties.";
3059d3ae10eSAlpana Kumari 
306bc1d29deSKrzysztof Grobelny                             if (properties.empty())
3079d3ae10eSAlpana Kumari                             {
3081e1e598dSJonathan Doman                                 sdbusplus::asio::getProperty<bool>(
309002d39b4SEd Tanous                                     *crow::connections::systemBus, service,
310002d39b4SEd Tanous                                     path,
3111e1e598dSJonathan Doman                                     "xyz.openbmc_project.State."
3121e1e598dSJonathan Doman                                     "Decorator.OperationalStatus",
3131e1e598dSJonathan Doman                                     "Functional",
314002d39b4SEd Tanous                                     [aResp](const boost::system::error_code ec3,
3151e1e598dSJonathan Doman                                             bool dimmState) {
316cb13a392SEd Tanous                                     if (ec3)
3179d3ae10eSAlpana Kumari                                     {
3189d3ae10eSAlpana Kumari                                         BMCWEB_LOG_ERROR
319002d39b4SEd Tanous                                             << "DBUS response error " << ec3;
3209d3ae10eSAlpana Kumari                                         return;
3219d3ae10eSAlpana Kumari                                     }
322002d39b4SEd Tanous                                     updateDimmProperties(aResp, dimmState);
3231e1e598dSJonathan Doman                                     });
324bc1d29deSKrzysztof Grobelny                                 return;
3259d3ae10eSAlpana Kumari                             }
326bc1d29deSKrzysztof Grobelny 
327bc1d29deSKrzysztof Grobelny                             const uint32_t* memorySizeInKB = nullptr;
328bc1d29deSKrzysztof Grobelny 
329bc1d29deSKrzysztof Grobelny                             const bool success =
330bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
331bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
332bc1d29deSKrzysztof Grobelny                                     properties, "MemorySizeInKB",
333bc1d29deSKrzysztof Grobelny                                     memorySizeInKB);
334bc1d29deSKrzysztof Grobelny 
335bc1d29deSKrzysztof Grobelny                             if (!success)
336bc1d29deSKrzysztof Grobelny                             {
337bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
338bc1d29deSKrzysztof Grobelny                                 return;
339bc1d29deSKrzysztof Grobelny                             }
340bc1d29deSKrzysztof Grobelny 
341bc1d29deSKrzysztof Grobelny                             if (memorySizeInKB != nullptr)
342bc1d29deSKrzysztof Grobelny                             {
343bc1d29deSKrzysztof Grobelny                                 nlohmann::json& totalMemory =
344bc1d29deSKrzysztof Grobelny                                     aResp->res
345bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
346bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"];
347bc1d29deSKrzysztof Grobelny                                 const uint64_t* preValue =
348bc1d29deSKrzysztof Grobelny                                     totalMemory.get_ptr<const uint64_t*>();
349bc1d29deSKrzysztof Grobelny                                 if (preValue == nullptr)
350bc1d29deSKrzysztof Grobelny                                 {
351bc1d29deSKrzysztof Grobelny                                     aResp->res
352bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
353bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
354bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024);
355bc1d29deSKrzysztof Grobelny                                 }
356bc1d29deSKrzysztof Grobelny                                 else
357bc1d29deSKrzysztof Grobelny                                 {
358bc1d29deSKrzysztof Grobelny                                     aResp->res
359bc1d29deSKrzysztof Grobelny                                         .jsonValue["MemorySummary"]
360bc1d29deSKrzysztof Grobelny                                                   ["TotalSystemMemoryGiB"] =
361bc1d29deSKrzysztof Grobelny                                         *memorySizeInKB / (1024 * 1024) +
362bc1d29deSKrzysztof Grobelny                                         *preValue;
363bc1d29deSKrzysztof Grobelny                                 }
364bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["MemorySummary"]["Status"]
365bc1d29deSKrzysztof Grobelny                                                     ["State"] = "Enabled";
366bc1d29deSKrzysztof Grobelny                             }
367bc1d29deSKrzysztof Grobelny                             });
3685bc2dc8eSJames Feist 
3695bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
3701abe55efSEd Tanous                     }
37104a258f4SEd Tanous                     else if (interfaceName ==
37204a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
3731abe55efSEd Tanous                     {
3741abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
37504a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
37657e8c9beSAlpana Kumari 
37703fbed92SAli Ahmed                         getProcessorSummary(aResp, connection.first, path);
3785bc2dc8eSJames Feist 
3795bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
3801abe55efSEd Tanous                     }
381002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
3821abe55efSEd Tanous                     {
3831abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
38404a258f4SEd Tanous                             << "Found UUID, now get its properties.";
385bc1d29deSKrzysztof Grobelny 
386bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
387bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
388bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
389168e20c1SEd Tanous                             [aResp](const boost::system::error_code ec3,
390b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
3911214b7e7SGunnar Mills                                         properties) {
392cb13a392SEd Tanous                             if (ec3)
3931abe55efSEd Tanous                             {
394002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
395002d39b4SEd Tanous                                                  << ec3;
396f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
397c5b2abe0SLewanczyk, Dawid                                 return;
398c5b2abe0SLewanczyk, Dawid                             }
399002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
400c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
40104a258f4SEd Tanous 
402bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
403bc1d29deSKrzysztof Grobelny 
404bc1d29deSKrzysztof Grobelny                             const bool success =
405bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
406bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
407bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
408bc1d29deSKrzysztof Grobelny 
409bc1d29deSKrzysztof Grobelny                             if (!success)
4101abe55efSEd Tanous                             {
411bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
412bc1d29deSKrzysztof Grobelny                                 return;
413bc1d29deSKrzysztof Grobelny                             }
414bc1d29deSKrzysztof Grobelny 
415bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
416bc1d29deSKrzysztof Grobelny                             {
417bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
41804a258f4SEd Tanous                                 if (valueStr.size() == 32)
4191abe55efSEd Tanous                                 {
420029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
421029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
422029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
423029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
42404a258f4SEd Tanous                                 }
425bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
426002d39b4SEd Tanous                                 aResp->res.jsonValue["UUID"] = valueStr;
427c5b2abe0SLewanczyk, Dawid                             }
428bc1d29deSKrzysztof Grobelny                             });
429c5b2abe0SLewanczyk, Dawid                     }
430029573d4SEd Tanous                     else if (interfaceName ==
431029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4321abe55efSEd Tanous                     {
433bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
434bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
435bc1d29deSKrzysztof Grobelny                             path,
436bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
437168e20c1SEd Tanous                             [aResp](const boost::system::error_code ec2,
438b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4391214b7e7SGunnar Mills                                         propertiesList) {
440cb13a392SEd Tanous                             if (ec2)
441029573d4SEd Tanous                             {
442e4a4b9a9SJames Feist                                 // doesn't have to include this
443e4a4b9a9SJames Feist                                 // interface
444029573d4SEd Tanous                                 return;
445029573d4SEd Tanous                             }
446002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
447029573d4SEd Tanous                                              << " properties for system";
448bc1d29deSKrzysztof Grobelny 
449bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
450bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
451bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
452bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
453bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
454bc1d29deSKrzysztof Grobelny 
455bc1d29deSKrzysztof Grobelny                             const bool success =
456bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
457bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
458bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
459bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
460bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
461bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
462bc1d29deSKrzysztof Grobelny 
463bc1d29deSKrzysztof Grobelny                             if (!success)
464029573d4SEd Tanous                             {
465bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
466bc1d29deSKrzysztof Grobelny                                 return;
467029573d4SEd Tanous                             }
468bc1d29deSKrzysztof Grobelny 
469bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
470bc1d29deSKrzysztof Grobelny                             {
471bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["PartNumber"] =
472bc1d29deSKrzysztof Grobelny                                     *partNumber;
473029573d4SEd Tanous                             }
474bc1d29deSKrzysztof Grobelny 
475bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
476bc1d29deSKrzysztof Grobelny                             {
477bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SerialNumber"] =
478bc1d29deSKrzysztof Grobelny                                     *serialNumber;
479bc1d29deSKrzysztof Grobelny                             }
480bc1d29deSKrzysztof Grobelny 
481bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
482bc1d29deSKrzysztof Grobelny                             {
483bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Manufacturer"] =
484bc1d29deSKrzysztof Grobelny                                     *manufacturer;
485bc1d29deSKrzysztof Grobelny                             }
486bc1d29deSKrzysztof Grobelny 
487bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
488bc1d29deSKrzysztof Grobelny                             {
489bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Model"] = *model;
490bc1d29deSKrzysztof Grobelny                             }
491bc1d29deSKrzysztof Grobelny 
492bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
493bc1d29deSKrzysztof Grobelny                             {
494bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SubModel"] = *subModel;
495fc5afcf9Sbeccabroek                             }
496c1e236a6SGunnar Mills 
497cb7e1e7bSAndrew Geissler                             // Grab the bios version
498eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
499eee0013eSWilly Tu                                 aResp, sw_util::biosPurpose, "BiosVersion",
500002d39b4SEd Tanous                                 false);
501bc1d29deSKrzysztof Grobelny                             });
502e4a4b9a9SJames Feist 
5031e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5041e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5051e1e598dSJonathan Doman                             path,
5061e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5071e1e598dSJonathan Doman                             "AssetTag",
5081e1e598dSJonathan Doman                             "AssetTag",
509168e20c1SEd Tanous                             [aResp](const boost::system::error_code ec2,
5101e1e598dSJonathan Doman                                     const std::string& value) {
511cb13a392SEd Tanous                             if (ec2)
512e4a4b9a9SJames Feist                             {
513e4a4b9a9SJames Feist                                 // doesn't have to include this
514e4a4b9a9SJames Feist                                 // interface
515e4a4b9a9SJames Feist                                 return;
516e4a4b9a9SJames Feist                             }
517e4a4b9a9SJames Feist 
5181e1e598dSJonathan Doman                             aResp->res.jsonValue["AssetTag"] = value;
5191e1e598dSJonathan Doman                             });
520029573d4SEd Tanous                     }
521029573d4SEd Tanous                 }
522bc1d29deSKrzysztof Grobelny                 break;
523029573d4SEd Tanous             }
524c5b2abe0SLewanczyk, Dawid         }
525c5b2abe0SLewanczyk, Dawid         },
526c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
527c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
528c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5296617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
5306617338dSEd Tanous         std::array<const char*, 5>{
5316617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
5326617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
5336617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
5346617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
5356617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
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",
553c5d03ff4SJennifer Lee         [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",
842978b8803SAndrew Geissler         [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 /**
859c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
860cd9a4666SKonstantin Aladyshev  *
861cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
862cd9a4666SKonstantin Aladyshev  *
863cd9a4666SKonstantin Aladyshev  * @return None.
864cd9a4666SKonstantin Aladyshev  */
865cd9a4666SKonstantin Aladyshev 
866c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
867cd9a4666SKonstantin Aladyshev {
8681e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8691e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
8701e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8711e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
872cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
8731e1e598dSJonathan Doman                 const std::string& bootType) {
874cd9a4666SKonstantin Aladyshev         if (ec)
875cd9a4666SKonstantin Aladyshev         {
876cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
877cd9a4666SKonstantin Aladyshev             return;
878cd9a4666SKonstantin Aladyshev         }
879cd9a4666SKonstantin Aladyshev 
8801e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
881cd9a4666SKonstantin Aladyshev 
882002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
883002d39b4SEd Tanous                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
884002d39b4SEd Tanous             {"Legacy", "UEFI"};
885cd9a4666SKonstantin Aladyshev 
8861e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
887cd9a4666SKonstantin Aladyshev         if (rfType.empty())
888cd9a4666SKonstantin Aladyshev         {
889cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
890cd9a4666SKonstantin Aladyshev             return;
891cd9a4666SKonstantin Aladyshev         }
892cd9a4666SKonstantin Aladyshev 
893cd9a4666SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
8941e1e598dSJonathan Doman         });
895cd9a4666SKonstantin Aladyshev }
896cd9a4666SKonstantin Aladyshev 
897cd9a4666SKonstantin Aladyshev /**
898c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
899491d8ee7SSantosh Puranik  *
900491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
901491d8ee7SSantosh Puranik  *
902491d8ee7SSantosh Puranik  * @return None.
903491d8ee7SSantosh Puranik  */
904c21865c4SKonstantin Aladyshev 
905c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
906491d8ee7SSantosh Puranik {
9071e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9081e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9091e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9101e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
911c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
9121e1e598dSJonathan Doman                 const std::string& bootModeStr) {
913491d8ee7SSantosh Puranik         if (ec)
914491d8ee7SSantosh Puranik         {
915491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
916491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
917491d8ee7SSantosh Puranik             return;
918491d8ee7SSantosh Puranik         }
919491d8ee7SSantosh Puranik 
9201e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
921491d8ee7SSantosh Puranik 
9220fda0f12SGeorge Liu         aResp->res
9230fda0f12SGeorge Liu             .jsonValue["Boot"]
924002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
925002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
926491d8ee7SSantosh Puranik 
9271e1e598dSJonathan Doman         if (bootModeStr !=
928491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
929491d8ee7SSantosh Puranik         {
9301e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
931491d8ee7SSantosh Puranik             if (!rfMode.empty())
932491d8ee7SSantosh Puranik             {
933491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
934491d8ee7SSantosh Puranik                     rfMode;
935491d8ee7SSantosh Puranik             }
936491d8ee7SSantosh Puranik         }
9371e1e598dSJonathan Doman         });
938491d8ee7SSantosh Puranik }
939491d8ee7SSantosh Puranik 
940491d8ee7SSantosh Puranik /**
941c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
942491d8ee7SSantosh Puranik  *
943491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
944491d8ee7SSantosh Puranik  *
945491d8ee7SSantosh Puranik  * @return None.
946491d8ee7SSantosh Puranik  */
947c21865c4SKonstantin Aladyshev 
948c21865c4SKonstantin Aladyshev inline void
949c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
950491d8ee7SSantosh Puranik {
9511e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9521e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9531e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9541e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
955c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
9561e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
957491d8ee7SSantosh Puranik         if (ec)
958491d8ee7SSantosh Puranik         {
959491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
9605ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
9615ef735c8SNan Zhou             {
9625ef735c8SNan Zhou                 return;
9635ef735c8SNan Zhou             }
964491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
965491d8ee7SSantosh Puranik             return;
966491d8ee7SSantosh Puranik         }
967491d8ee7SSantosh Puranik 
9681e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
969491d8ee7SSantosh Puranik 
9701e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
971491d8ee7SSantosh Puranik         if (!rfSource.empty())
972491d8ee7SSantosh Puranik         {
973002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
974491d8ee7SSantosh Puranik         }
975cd9a4666SKonstantin Aladyshev 
976cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
977cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
978c21865c4SKonstantin Aladyshev         getBootOverrideMode(aResp);
9791e1e598dSJonathan Doman         });
980491d8ee7SSantosh Puranik }
981491d8ee7SSantosh Puranik 
982491d8ee7SSantosh Puranik /**
983c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
984c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
985c21865c4SKonstantin Aladyshev  * state
986491d8ee7SSantosh Puranik  *
987491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
988491d8ee7SSantosh Puranik  *
989491d8ee7SSantosh Puranik  * @return None.
990491d8ee7SSantosh Puranik  */
991491d8ee7SSantosh Puranik 
992c21865c4SKonstantin Aladyshev inline void
993c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
994c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
995c21865c4SKonstantin Aladyshev {
996c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
997c21865c4SKonstantin Aladyshev     {
998c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
999c21865c4SKonstantin Aladyshev         return;
1000c21865c4SKonstantin Aladyshev     }
1001c21865c4SKonstantin Aladyshev 
1002c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1003c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10041e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10051e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10061e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10071e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10081e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
1009491d8ee7SSantosh Puranik         if (ec)
1010491d8ee7SSantosh Puranik         {
1011491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1012c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1013491d8ee7SSantosh Puranik             return;
1014491d8ee7SSantosh Puranik         }
1015491d8ee7SSantosh Puranik 
1016c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1017c21865c4SKonstantin Aladyshev         {
1018002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1019c21865c4SKonstantin Aladyshev         }
1020c21865c4SKonstantin Aladyshev         else
1021c21865c4SKonstantin Aladyshev         {
1022c21865c4SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1023c21865c4SKonstantin Aladyshev                 "Continuous";
1024c21865c4SKonstantin Aladyshev         }
10251e1e598dSJonathan Doman         });
1026491d8ee7SSantosh Puranik }
1027491d8ee7SSantosh Puranik 
1028491d8ee7SSantosh Puranik /**
1029c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1030c21865c4SKonstantin Aladyshev  *
1031c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1032c21865c4SKonstantin Aladyshev  *
1033c21865c4SKonstantin Aladyshev  * @return None.
1034c21865c4SKonstantin Aladyshev  */
1035c21865c4SKonstantin Aladyshev 
1036c21865c4SKonstantin Aladyshev inline void
1037c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1038c21865c4SKonstantin Aladyshev {
10391e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10401e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10411e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10421e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1043c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
10441e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1045c21865c4SKonstantin Aladyshev         if (ec)
1046c21865c4SKonstantin Aladyshev         {
1047c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10485ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10495ef735c8SNan Zhou             {
10505ef735c8SNan Zhou                 return;
10515ef735c8SNan Zhou             }
1052c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1053c21865c4SKonstantin Aladyshev             return;
1054c21865c4SKonstantin Aladyshev         }
1055c21865c4SKonstantin Aladyshev 
10561e1e598dSJonathan Doman         processBootOverrideEnable(aResp, bootOverrideEnable);
10571e1e598dSJonathan Doman         });
1058c21865c4SKonstantin Aladyshev }
1059c21865c4SKonstantin Aladyshev 
1060c21865c4SKonstantin Aladyshev /**
1061c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1062c21865c4SKonstantin Aladyshev  *
1063c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1064c21865c4SKonstantin Aladyshev  *
1065c21865c4SKonstantin Aladyshev  * @return None.
1066c21865c4SKonstantin Aladyshev  */
1067c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1068c21865c4SKonstantin Aladyshev {
1069c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1070c21865c4SKonstantin Aladyshev 
1071c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1072c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1073c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1074c21865c4SKonstantin Aladyshev }
1075c21865c4SKonstantin Aladyshev 
1076c21865c4SKonstantin Aladyshev /**
1077c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1078c0557e1aSGunnar Mills  *
1079c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1080c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1081c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1082c0557e1aSGunnar Mills  * last power operation time.
1083c0557e1aSGunnar Mills  *
1084c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1085c0557e1aSGunnar Mills  *
1086c0557e1aSGunnar Mills  * @return None.
1087c0557e1aSGunnar Mills  */
10888d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1089c0557e1aSGunnar Mills {
1090c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1091c0557e1aSGunnar Mills 
10921e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
10931e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
10941e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
10951e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
10961e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
1097c0557e1aSGunnar Mills         if (ec)
1098c0557e1aSGunnar Mills         {
1099c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1100c0557e1aSGunnar Mills             return;
1101c0557e1aSGunnar Mills         }
1102c0557e1aSGunnar Mills 
1103c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1104c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11051e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1106c0557e1aSGunnar Mills 
1107c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1108c0557e1aSGunnar Mills         aResp->res.jsonValue["LastResetTime"] =
11092b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11101e1e598dSJonathan Doman         });
1111c0557e1aSGunnar Mills }
1112c0557e1aSGunnar Mills 
1113c0557e1aSGunnar Mills /**
11146bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11156bd5a8d2SGunnar Mills  *
11166bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11176bd5a8d2SGunnar Mills  *
11186bd5a8d2SGunnar Mills  * @return None.
11196bd5a8d2SGunnar Mills  */
11208d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11216bd5a8d2SGunnar Mills {
11226bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
11236bd5a8d2SGunnar Mills 
11241e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11251e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11261e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
11271e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
11281e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
11296bd5a8d2SGunnar Mills         if (ec)
11306bd5a8d2SGunnar Mills         {
11316bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
11326bd5a8d2SGunnar Mills             return;
11336bd5a8d2SGunnar Mills         }
11346bd5a8d2SGunnar Mills 
11351e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1136e05aec50SEd Tanous         if (autoRebootEnabled)
11376bd5a8d2SGunnar Mills         {
11386bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
11396bd5a8d2SGunnar Mills                 "RetryAttempts";
11406bd5a8d2SGunnar Mills             // If AutomaticRetry (AutoReboot) is enabled see how many
11416bd5a8d2SGunnar Mills             // attempts are left
11421e1e598dSJonathan Doman             sdbusplus::asio::getProperty<uint32_t>(
1143002d39b4SEd Tanous                 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
11441e1e598dSJonathan Doman                 "/xyz/openbmc_project/state/host0",
11451e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.Boot.RebootAttempts",
11461e1e598dSJonathan Doman                 "AttemptsLeft",
1147cb13a392SEd Tanous                 [aResp](const boost::system::error_code ec2,
1148914e2d5dSEd Tanous                         const uint32_t autoRebootAttemptsLeft) {
1149cb13a392SEd Tanous                 if (ec2)
11506bd5a8d2SGunnar Mills                 {
1151cb13a392SEd Tanous                     BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
11526bd5a8d2SGunnar Mills                     return;
11536bd5a8d2SGunnar Mills                 }
11546bd5a8d2SGunnar Mills 
11556bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
11561e1e598dSJonathan Doman                                  << autoRebootAttemptsLeft;
11576bd5a8d2SGunnar Mills 
11586bd5a8d2SGunnar Mills                 aResp->res
1159002d39b4SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
11601e1e598dSJonathan Doman                     autoRebootAttemptsLeft;
11611e1e598dSJonathan Doman                 });
11626bd5a8d2SGunnar Mills         }
11636bd5a8d2SGunnar Mills         else
11646bd5a8d2SGunnar Mills         {
1165002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
11666bd5a8d2SGunnar Mills         }
11676bd5a8d2SGunnar Mills 
11686bd5a8d2SGunnar Mills         // Not on D-Bus. Hardcoded here:
11696bd5a8d2SGunnar Mills         // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
11706bd5a8d2SGunnar Mills         aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
117169f35306SGunnar Mills 
117269f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
117369f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
117469f35306SGunnar Mills         // RetryAttempts.
1175002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
11760fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
11770fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
11781e1e598dSJonathan Doman         });
11796bd5a8d2SGunnar Mills }
11806bd5a8d2SGunnar Mills 
11816bd5a8d2SGunnar Mills /**
1182c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1183c6a620f2SGeorge Liu  *
1184c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1185c6a620f2SGeorge Liu  *
1186c6a620f2SGeorge Liu  * @return None.
1187c6a620f2SGeorge Liu  */
11888d1b46d7Szhanghch05 inline void
11898d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1190c6a620f2SGeorge Liu {
1191c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1192c6a620f2SGeorge Liu 
11931e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
11941e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11951e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
11961e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
11971e1e598dSJonathan Doman         [aResp](const boost::system::error_code ec, const std::string& policy) {
1198c6a620f2SGeorge Liu         if (ec)
1199c6a620f2SGeorge Liu         {
1200c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1201c6a620f2SGeorge Liu             return;
1202c6a620f2SGeorge Liu         }
1203c6a620f2SGeorge Liu 
12040fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
12050fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1206c6a620f2SGeorge Liu              "AlwaysOn"},
12070fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1208c6a620f2SGeorge Liu              "AlwaysOff"},
12090fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
12104ed47cb8SMatthew Barth              "LastState"},
12114ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
12124ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
12134ed47cb8SMatthew Barth              "AlwaysOff"}};
1214c6a620f2SGeorge Liu 
12151e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1216c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1217c6a620f2SGeorge Liu         {
1218c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1219c6a620f2SGeorge Liu             return;
1220c6a620f2SGeorge Liu         }
1221c6a620f2SGeorge Liu 
1222c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
12231e1e598dSJonathan Doman         });
1224c6a620f2SGeorge Liu }
1225c6a620f2SGeorge Liu 
1226c6a620f2SGeorge Liu /**
12271981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
12281981771bSAli Ahmed  * TPM is required for booting the host.
12291981771bSAli Ahmed  *
12301981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
12311981771bSAli Ahmed  *
12321981771bSAli Ahmed  * @return None.
12331981771bSAli Ahmed  */
12341981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
12351981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12361981771bSAli Ahmed {
12371981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
12381981771bSAli Ahmed 
12391981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
1240b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
1241b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
12421981771bSAli Ahmed         if (ec)
12431981771bSAli Ahmed         {
1244002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1245002d39b4SEd Tanous                              << ec;
12461981771bSAli Ahmed             // This is an optional D-Bus object so just return if
12471981771bSAli Ahmed             // error occurs
12481981771bSAli Ahmed             return;
12491981771bSAli Ahmed         }
125026f6976fSEd Tanous         if (subtree.empty())
12511981771bSAli Ahmed         {
12521981771bSAli Ahmed             // As noted above, this is an optional interface so just return
12531981771bSAli Ahmed             // if there is no instance found
12541981771bSAli Ahmed             return;
12551981771bSAli Ahmed         }
12561981771bSAli Ahmed 
12571981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
12581981771bSAli Ahmed         if (subtree.size() > 1)
12591981771bSAli Ahmed         {
12601981771bSAli Ahmed             BMCWEB_LOG_DEBUG
12611981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
12621981771bSAli Ahmed                 << subtree.size();
12631981771bSAli Ahmed             // Throw an internal Error and return
12641981771bSAli Ahmed             messages::internalError(aResp->res);
12651981771bSAli Ahmed             return;
12661981771bSAli Ahmed         }
12671981771bSAli Ahmed 
12681981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
12691981771bSAli Ahmed         // field
12701981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
12711981771bSAli Ahmed         {
12721981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
12731981771bSAli Ahmed             messages::internalError(aResp->res);
12741981771bSAli Ahmed             return;
12751981771bSAli Ahmed         }
12761981771bSAli Ahmed 
12771981771bSAli Ahmed         const std::string& path = subtree[0].first;
12781981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
12791981771bSAli Ahmed 
12801981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
12811e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
12821e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
12831e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
12848a592810SEd Tanous             [aResp](const boost::system::error_code ec2, bool tpmRequired) {
12858a592810SEd Tanous             if (ec2)
12861981771bSAli Ahmed             {
1287002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
12888a592810SEd Tanous                                  << ec2;
12891981771bSAli Ahmed                 messages::internalError(aResp->res);
12901981771bSAli Ahmed                 return;
12911981771bSAli Ahmed             }
12921981771bSAli Ahmed 
12931e1e598dSJonathan Doman             if (tpmRequired)
12941981771bSAli Ahmed             {
1295002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
12961981771bSAli Ahmed                     "Required";
12971981771bSAli Ahmed             }
12981981771bSAli Ahmed             else
12991981771bSAli Ahmed             {
1300002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
13011981771bSAli Ahmed                     "Disabled";
13021981771bSAli Ahmed             }
13031e1e598dSJonathan Doman             });
13041981771bSAli Ahmed         },
13051981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
13061981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
13071981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
13081981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
13091981771bSAli Ahmed }
13101981771bSAli Ahmed 
13111981771bSAli Ahmed /**
13121c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
13131c05dae3SAli Ahmed  * TPM is required for booting the host.
13141c05dae3SAli Ahmed  *
13151c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
13161c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
13171c05dae3SAli Ahmed  *
13181c05dae3SAli Ahmed  * @return None.
13191c05dae3SAli Ahmed  */
13201c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
13211c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
13221c05dae3SAli Ahmed {
13231c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
13241c05dae3SAli Ahmed 
13251c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
1326b9d36b47SEd Tanous         [aResp, tpmRequired](const boost::system::error_code ec,
1327b9d36b47SEd Tanous                              dbus::utility::MapperGetSubTreeResponse& subtree) {
13281c05dae3SAli Ahmed         if (ec)
13291c05dae3SAli Ahmed         {
1330002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1331002d39b4SEd Tanous                              << ec;
13321c05dae3SAli Ahmed             messages::internalError(aResp->res);
13331c05dae3SAli Ahmed             return;
13341c05dae3SAli Ahmed         }
133526f6976fSEd Tanous         if (subtree.empty())
13361c05dae3SAli Ahmed         {
13371c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
13381c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
13391c05dae3SAli Ahmed             return;
13401c05dae3SAli Ahmed         }
13411c05dae3SAli Ahmed 
13421c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
13431c05dae3SAli Ahmed         if (subtree.size() > 1)
13441c05dae3SAli Ahmed         {
13451c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
13461c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13471c05dae3SAli Ahmed                 << subtree.size();
13481c05dae3SAli Ahmed             // Throw an internal Error and return
13491c05dae3SAli Ahmed             messages::internalError(aResp->res);
13501c05dae3SAli Ahmed             return;
13511c05dae3SAli Ahmed         }
13521c05dae3SAli Ahmed 
13531c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
13541c05dae3SAli Ahmed         // field
13551c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13561c05dae3SAli Ahmed         {
13571c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13581c05dae3SAli Ahmed             messages::internalError(aResp->res);
13591c05dae3SAli Ahmed             return;
13601c05dae3SAli Ahmed         }
13611c05dae3SAli Ahmed 
13621c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
13631c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
13641c05dae3SAli Ahmed 
13651c05dae3SAli Ahmed         if (serv.empty())
13661c05dae3SAli Ahmed         {
13671c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
13681c05dae3SAli Ahmed             messages::internalError(aResp->res);
13691c05dae3SAli Ahmed             return;
13701c05dae3SAli Ahmed         }
13711c05dae3SAli Ahmed 
13721c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
13731c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
13748a592810SEd Tanous             [aResp](const boost::system::error_code ec2) {
13758a592810SEd Tanous             if (ec2)
13761c05dae3SAli Ahmed             {
13770fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
13780fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
13798a592810SEd Tanous                     << ec2;
13801c05dae3SAli Ahmed                 messages::internalError(aResp->res);
13811c05dae3SAli Ahmed                 return;
13821c05dae3SAli Ahmed             }
13831c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
13841c05dae3SAli Ahmed             },
13851c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
13861c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1387168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
13881c05dae3SAli Ahmed         },
13891c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
13901c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
13911c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
13921c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
13931c05dae3SAli Ahmed }
13941c05dae3SAli Ahmed 
13951c05dae3SAli Ahmed /**
1396491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1397491d8ee7SSantosh Puranik  *
1398491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1399cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1400cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1401cd9a4666SKonstantin Aladyshev  */
1402cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1403cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1404cd9a4666SKonstantin Aladyshev {
1405c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1406cd9a4666SKonstantin Aladyshev 
1407c21865c4SKonstantin Aladyshev     if (!bootType)
1408cd9a4666SKonstantin Aladyshev     {
1409c21865c4SKonstantin Aladyshev         return;
1410c21865c4SKonstantin Aladyshev     }
1411c21865c4SKonstantin Aladyshev 
1412cd9a4666SKonstantin Aladyshev     // Source target specified
1413cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1414cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1415cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1416cd9a4666SKonstantin Aladyshev     {
1417cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1418cd9a4666SKonstantin Aladyshev     }
1419cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1420cd9a4666SKonstantin Aladyshev     {
1421cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1422cd9a4666SKonstantin Aladyshev     }
1423cd9a4666SKonstantin Aladyshev     else
1424cd9a4666SKonstantin Aladyshev     {
1425cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1426cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1427cd9a4666SKonstantin Aladyshev                          << *bootType;
1428cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1429cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1430cd9a4666SKonstantin Aladyshev         return;
1431cd9a4666SKonstantin Aladyshev     }
1432cd9a4666SKonstantin Aladyshev 
1433cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1434cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1435cd9a4666SKonstantin Aladyshev 
1436cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1437c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1438cd9a4666SKonstantin Aladyshev         if (ec)
1439cd9a4666SKonstantin Aladyshev         {
1440cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1441cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1442cd9a4666SKonstantin Aladyshev             {
1443cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1444cd9a4666SKonstantin Aladyshev                 return;
1445cd9a4666SKonstantin Aladyshev             }
1446cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1447cd9a4666SKonstantin Aladyshev             return;
1448cd9a4666SKonstantin Aladyshev         }
1449cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1450cd9a4666SKonstantin Aladyshev         },
1451c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1452c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1453cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1454cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1455168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1456cd9a4666SKonstantin Aladyshev }
1457cd9a4666SKonstantin Aladyshev 
1458cd9a4666SKonstantin Aladyshev /**
1459cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1460cd9a4666SKonstantin Aladyshev  *
1461cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1462c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1463c21865c4SKonstantin Aladyshev  * @return Integer error code.
1464c21865c4SKonstantin Aladyshev  */
1465c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1466c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1467c21865c4SKonstantin Aladyshev {
1468c21865c4SKonstantin Aladyshev     if (!bootEnable)
1469c21865c4SKonstantin Aladyshev     {
1470c21865c4SKonstantin Aladyshev         return;
1471c21865c4SKonstantin Aladyshev     }
1472c21865c4SKonstantin Aladyshev     // Source target specified
1473c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1474c21865c4SKonstantin Aladyshev 
1475c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1476c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1477c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1478c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1479c21865c4SKonstantin Aladyshev     {
1480c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1481c21865c4SKonstantin Aladyshev     }
1482c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1483c21865c4SKonstantin Aladyshev     {
1484c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1485c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1486c21865c4SKonstantin Aladyshev     }
1487c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1488c21865c4SKonstantin Aladyshev     {
1489c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1490c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1491c21865c4SKonstantin Aladyshev     }
1492c21865c4SKonstantin Aladyshev     else
1493c21865c4SKonstantin Aladyshev     {
14940fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
14950fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1496c21865c4SKonstantin Aladyshev             << *bootEnable;
1497c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1498c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1499c21865c4SKonstantin Aladyshev         return;
1500c21865c4SKonstantin Aladyshev     }
1501c21865c4SKonstantin Aladyshev 
1502c21865c4SKonstantin Aladyshev     // Act on validated parameters
1503c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1504c21865c4SKonstantin Aladyshev 
1505c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
15068a592810SEd Tanous         [aResp](const boost::system::error_code ec2) {
15078a592810SEd Tanous         if (ec2)
1508c21865c4SKonstantin Aladyshev         {
15098a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1510c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1511c21865c4SKonstantin Aladyshev             return;
1512c21865c4SKonstantin Aladyshev         }
1513c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1514c21865c4SKonstantin Aladyshev         },
1515c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1516c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1517c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1518c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1519168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1520c21865c4SKonstantin Aladyshev 
1521c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1522c21865c4SKonstantin Aladyshev     {
1523c21865c4SKonstantin Aladyshev         return;
1524c21865c4SKonstantin Aladyshev     }
1525c21865c4SKonstantin Aladyshev 
1526c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1527c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1528c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1529c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1530c21865c4SKonstantin Aladyshev 
1531c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1532c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1533c21865c4SKonstantin Aladyshev         if (ec)
1534c21865c4SKonstantin Aladyshev         {
1535c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1536c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1537c21865c4SKonstantin Aladyshev             return;
1538c21865c4SKonstantin Aladyshev         }
1539c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1540c21865c4SKonstantin Aladyshev         },
1541c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1542c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1543c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1544c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1545168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1546c21865c4SKonstantin Aladyshev }
1547c21865c4SKonstantin Aladyshev 
1548c21865c4SKonstantin Aladyshev /**
1549c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1550c21865c4SKonstantin Aladyshev  *
1551c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1552491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1553491d8ee7SSantosh Puranik  *
1554265c1602SJohnathan Mantey  * @return Integer error code.
1555491d8ee7SSantosh Puranik  */
1556cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1557cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1558491d8ee7SSantosh Puranik {
1559c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1560c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1561944ffaf9SJohnathan Mantey 
1562c21865c4SKonstantin Aladyshev     if (!bootSource)
1563491d8ee7SSantosh Puranik     {
1564c21865c4SKonstantin Aladyshev         return;
1565c21865c4SKonstantin Aladyshev     }
1566c21865c4SKonstantin Aladyshev 
1567491d8ee7SSantosh Puranik     // Source target specified
1568491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1569491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1570e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1571e662eae8SEd Tanous         0)
1572491d8ee7SSantosh Puranik     {
1573944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1574944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1575491d8ee7SSantosh Puranik             << *bootSource;
1576491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1577491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1578491d8ee7SSantosh Puranik         return;
1579491d8ee7SSantosh Puranik     }
1580491d8ee7SSantosh Puranik 
1581944ffaf9SJohnathan Mantey     // Act on validated parameters
1582944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1583944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1584944ffaf9SJohnathan Mantey 
1585491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1586491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1587491d8ee7SSantosh Puranik         if (ec)
1588491d8ee7SSantosh Puranik         {
1589491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1590491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1591491d8ee7SSantosh Puranik             return;
1592491d8ee7SSantosh Puranik         }
1593491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1594491d8ee7SSantosh Puranik         },
1595c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1596c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1597491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1598491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1599168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1600944ffaf9SJohnathan Mantey 
1601491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1602491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1603491d8ee7SSantosh Puranik         if (ec)
1604491d8ee7SSantosh Puranik         {
1605491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1606491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1607491d8ee7SSantosh Puranik             return;
1608491d8ee7SSantosh Puranik         }
1609491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1610491d8ee7SSantosh Puranik         },
1611c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1612c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1613491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1614491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1615168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1616cd9a4666SKonstantin Aladyshev }
1617944ffaf9SJohnathan Mantey 
1618cd9a4666SKonstantin Aladyshev /**
1619c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1620491d8ee7SSantosh Puranik  *
1621491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1622491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1623cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1624491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1625491d8ee7SSantosh Puranik  *
1626265c1602SJohnathan Mantey  * @return Integer error code.
1627491d8ee7SSantosh Puranik  */
1628c21865c4SKonstantin Aladyshev 
1629c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1630c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1631c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1632c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1633491d8ee7SSantosh Puranik {
1634491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1635491d8ee7SSantosh Puranik 
1636c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1637c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1638c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1639491d8ee7SSantosh Puranik }
1640491d8ee7SSantosh Puranik 
1641c6a620f2SGeorge Liu /**
164298e386ecSGunnar Mills  * @brief Sets AssetTag
164398e386ecSGunnar Mills  *
164498e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
164598e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
164698e386ecSGunnar Mills  *
164798e386ecSGunnar Mills  * @return None.
164898e386ecSGunnar Mills  */
16498d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
165098e386ecSGunnar Mills                         const std::string& assetTag)
165198e386ecSGunnar Mills {
165298e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
1653b9d36b47SEd Tanous         [aResp,
1654b9d36b47SEd Tanous          assetTag](const boost::system::error_code ec,
1655b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
165698e386ecSGunnar Mills         if (ec)
165798e386ecSGunnar Mills         {
165898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
165998e386ecSGunnar Mills             messages::internalError(aResp->res);
166098e386ecSGunnar Mills             return;
166198e386ecSGunnar Mills         }
166226f6976fSEd Tanous         if (subtree.empty())
166398e386ecSGunnar Mills         {
166498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
166598e386ecSGunnar Mills             messages::internalError(aResp->res);
166698e386ecSGunnar Mills             return;
166798e386ecSGunnar Mills         }
166898e386ecSGunnar Mills         // Assume only 1 system D-Bus object
166998e386ecSGunnar Mills         // Throw an error if there is more than 1
167098e386ecSGunnar Mills         if (subtree.size() > 1)
167198e386ecSGunnar Mills         {
167298e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
167398e386ecSGunnar Mills             messages::internalError(aResp->res);
167498e386ecSGunnar Mills             return;
167598e386ecSGunnar Mills         }
167698e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
167798e386ecSGunnar Mills         {
167898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
167998e386ecSGunnar Mills             messages::internalError(aResp->res);
168098e386ecSGunnar Mills             return;
168198e386ecSGunnar Mills         }
168298e386ecSGunnar Mills 
168398e386ecSGunnar Mills         const std::string& path = subtree[0].first;
168498e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
168598e386ecSGunnar Mills 
168698e386ecSGunnar Mills         if (service.empty())
168798e386ecSGunnar Mills         {
168898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
168998e386ecSGunnar Mills             messages::internalError(aResp->res);
169098e386ecSGunnar Mills             return;
169198e386ecSGunnar Mills         }
169298e386ecSGunnar Mills 
169398e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
169498e386ecSGunnar Mills             [aResp](const boost::system::error_code ec2) {
169598e386ecSGunnar Mills             if (ec2)
169698e386ecSGunnar Mills             {
1697002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1698002d39b4SEd Tanous                                  << ec2;
169998e386ecSGunnar Mills                 messages::internalError(aResp->res);
170098e386ecSGunnar Mills                 return;
170198e386ecSGunnar Mills             }
170298e386ecSGunnar Mills             },
170398e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
170498e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1705168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
170698e386ecSGunnar Mills         },
170798e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
170898e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
170998e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
171098e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
171198e386ecSGunnar Mills         std::array<const char*, 1>{
171298e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
171398e386ecSGunnar Mills }
171498e386ecSGunnar Mills 
171598e386ecSGunnar Mills /**
171669f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
171769f35306SGunnar Mills  *
171869f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
171969f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
172069f35306SGunnar Mills  *
172169f35306SGunnar Mills  * @return None.
172269f35306SGunnar Mills  */
17238d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1724f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
172569f35306SGunnar Mills {
172669f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
172769f35306SGunnar Mills 
172869f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1729543f4400SEd Tanous     bool autoRebootEnabled = false;
173069f35306SGunnar Mills 
173169f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
173269f35306SGunnar Mills     {
173369f35306SGunnar Mills         autoRebootEnabled = false;
173469f35306SGunnar Mills     }
173569f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
173669f35306SGunnar Mills     {
173769f35306SGunnar Mills         autoRebootEnabled = true;
173869f35306SGunnar Mills     }
173969f35306SGunnar Mills     else
174069f35306SGunnar Mills     {
17410fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
174269f35306SGunnar Mills                          << automaticRetryConfig;
174369f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
174469f35306SGunnar Mills                                          "AutomaticRetryConfig");
174569f35306SGunnar Mills         return;
174669f35306SGunnar Mills     }
174769f35306SGunnar Mills 
174869f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
174969f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
175069f35306SGunnar Mills         if (ec)
175169f35306SGunnar Mills         {
175269f35306SGunnar Mills             messages::internalError(aResp->res);
175369f35306SGunnar Mills             return;
175469f35306SGunnar Mills         }
175569f35306SGunnar Mills         },
175669f35306SGunnar Mills         "xyz.openbmc_project.Settings",
175769f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
175869f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
175969f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1760168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
176169f35306SGunnar Mills }
176269f35306SGunnar Mills 
176369f35306SGunnar Mills /**
1764c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1765c6a620f2SGeorge Liu  *
1766c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1767c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1768c6a620f2SGeorge Liu  *
1769c6a620f2SGeorge Liu  * @return None.
1770c6a620f2SGeorge Liu  */
17718d1b46d7Szhanghch05 inline void
17728d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
17734e69c904SGunnar Mills                           const std::string& policy)
1774c6a620f2SGeorge Liu {
1775c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1776c6a620f2SGeorge Liu 
1777c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
17780fda0f12SGeorge Liu         {"AlwaysOn",
17790fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
17800fda0f12SGeorge Liu         {"AlwaysOff",
17810fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
17820fda0f12SGeorge Liu         {"LastState",
17830fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1784c6a620f2SGeorge Liu 
1785c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1786c6a620f2SGeorge Liu 
17874e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1788c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1789c6a620f2SGeorge Liu     {
17904e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
17914e69c904SGunnar Mills                                          "PowerRestorePolicy");
1792c6a620f2SGeorge Liu         return;
1793c6a620f2SGeorge Liu     }
1794c6a620f2SGeorge Liu 
1795c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1796c6a620f2SGeorge Liu 
1797c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1798c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1799c6a620f2SGeorge Liu         if (ec)
1800c6a620f2SGeorge Liu         {
1801c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1802c6a620f2SGeorge Liu             return;
1803c6a620f2SGeorge Liu         }
1804c6a620f2SGeorge Liu         },
1805c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1806c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1807c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1808c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1809168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1810c6a620f2SGeorge Liu }
1811c6a620f2SGeorge Liu 
1812a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1813a6349918SAppaRao Puli /**
1814a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1815a6349918SAppaRao Puli  *
1816a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1817a6349918SAppaRao Puli  *
1818a6349918SAppaRao Puli  * @return None.
1819a6349918SAppaRao Puli  */
18208d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1821a6349918SAppaRao Puli {
1822a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1823bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1824bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1825bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
1826a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
1827b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1828b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1829b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
183050626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
183150626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
183250626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
183350626f4fSJames Feist 
1834a6349918SAppaRao Puli         if (ec)
1835a6349918SAppaRao Puli         {
1836a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1837b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1838b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1839a6349918SAppaRao Puli             return;
1840a6349918SAppaRao Puli         }
1841a6349918SAppaRao Puli 
1842a6349918SAppaRao Puli         const bool* provState = nullptr;
1843a6349918SAppaRao Puli         const bool* lockState = nullptr;
1844bc1d29deSKrzysztof Grobelny 
1845bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
18460d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
18470d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1848bc1d29deSKrzysztof Grobelny 
1849bc1d29deSKrzysztof Grobelny         if (!success)
1850a6349918SAppaRao Puli         {
1851bc1d29deSKrzysztof Grobelny             messages::internalError(aResp->res);
1852bc1d29deSKrzysztof Grobelny             return;
1853a6349918SAppaRao Puli         }
1854a6349918SAppaRao Puli 
1855a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1856a6349918SAppaRao Puli         {
1857a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1858a6349918SAppaRao Puli             messages::internalError(aResp->res);
1859a6349918SAppaRao Puli             return;
1860a6349918SAppaRao Puli         }
1861a6349918SAppaRao Puli 
1862a6349918SAppaRao Puli         if (*provState == true)
1863a6349918SAppaRao Puli         {
1864a6349918SAppaRao Puli             if (*lockState == true)
1865a6349918SAppaRao Puli             {
1866a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1867a6349918SAppaRao Puli             }
1868a6349918SAppaRao Puli             else
1869a6349918SAppaRao Puli             {
1870a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1871a6349918SAppaRao Puli             }
1872a6349918SAppaRao Puli         }
1873a6349918SAppaRao Puli         else
1874a6349918SAppaRao Puli         {
1875a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1876a6349918SAppaRao Puli         }
1877bc1d29deSKrzysztof Grobelny         });
1878a6349918SAppaRao Puli }
1879a6349918SAppaRao Puli #endif
1880a6349918SAppaRao Puli 
1881491d8ee7SSantosh Puranik /**
18823a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
18833a2d0424SChris Cain  *
18843a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
18853a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
18863a2d0424SChris Cain  *
18873a2d0424SChris Cain  * @return None.
18883a2d0424SChris Cain  */
18893a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18903a2d0424SChris Cain                                const std::string& modeValue)
18913a2d0424SChris Cain {
18920fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
18933a2d0424SChris Cain     {
18943a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
18953a2d0424SChris Cain     }
18960fda0f12SGeorge Liu     else if (
18970fda0f12SGeorge Liu         modeValue ==
18980fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
18993a2d0424SChris Cain     {
19003a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
19013a2d0424SChris Cain     }
19020fda0f12SGeorge Liu     else if (modeValue ==
19030fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
19043a2d0424SChris Cain     {
19053a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
19063a2d0424SChris Cain     }
19070fda0f12SGeorge Liu     else if (modeValue ==
19080fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
19093a2d0424SChris Cain     {
19103a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
19113a2d0424SChris Cain     }
19123a2d0424SChris Cain     else
19133a2d0424SChris Cain     {
19143a2d0424SChris Cain         // Any other values would be invalid
19153a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
19163a2d0424SChris Cain         messages::internalError(aResp->res);
19173a2d0424SChris Cain     }
19183a2d0424SChris Cain }
19193a2d0424SChris Cain 
19203a2d0424SChris Cain /**
19213a2d0424SChris Cain  * @brief Retrieves system power mode
19223a2d0424SChris Cain  *
19233a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
19243a2d0424SChris Cain  *
19253a2d0424SChris Cain  * @return None.
19263a2d0424SChris Cain  */
19273a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
19283a2d0424SChris Cain {
19293a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
19303a2d0424SChris Cain 
19313a2d0424SChris Cain     // Get Power Mode object path:
19323a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
1933b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
1934b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
19353a2d0424SChris Cain         if (ec)
19363a2d0424SChris Cain         {
1937002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1938002d39b4SEd Tanous                              << ec;
19393a2d0424SChris Cain             // This is an optional D-Bus object so just return if
19403a2d0424SChris Cain             // error occurs
19413a2d0424SChris Cain             return;
19423a2d0424SChris Cain         }
19433a2d0424SChris Cain         if (subtree.empty())
19443a2d0424SChris Cain         {
19453a2d0424SChris Cain             // As noted above, this is an optional interface so just return
19463a2d0424SChris Cain             // if there is no instance found
19473a2d0424SChris Cain             return;
19483a2d0424SChris Cain         }
19493a2d0424SChris Cain         if (subtree.size() > 1)
19503a2d0424SChris Cain         {
19513a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
19523a2d0424SChris Cain             // error
19533a2d0424SChris Cain             BMCWEB_LOG_DEBUG
19543a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
19553a2d0424SChris Cain                 << subtree.size();
19563a2d0424SChris Cain             messages::internalError(aResp->res);
19573a2d0424SChris Cain             return;
19583a2d0424SChris Cain         }
19593a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
19603a2d0424SChris Cain         {
19613a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
19623a2d0424SChris Cain             messages::internalError(aResp->res);
19633a2d0424SChris Cain             return;
19643a2d0424SChris Cain         }
19653a2d0424SChris Cain         const std::string& path = subtree[0].first;
19663a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
19673a2d0424SChris Cain         if (service.empty())
19683a2d0424SChris Cain         {
19693a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
19703a2d0424SChris Cain             messages::internalError(aResp->res);
19713a2d0424SChris Cain             return;
19723a2d0424SChris Cain         }
19733a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
19741e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
19751e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
19761e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
19778a592810SEd Tanous             [aResp](const boost::system::error_code ec2,
19781e1e598dSJonathan Doman                     const std::string& pmode) {
19798a592810SEd Tanous             if (ec2)
19803a2d0424SChris Cain             {
1981002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
19828a592810SEd Tanous                                  << ec2;
19833a2d0424SChris Cain                 messages::internalError(aResp->res);
19843a2d0424SChris Cain                 return;
19853a2d0424SChris Cain             }
19863a2d0424SChris Cain 
1987002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
1988002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
19893a2d0424SChris Cain 
19901e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
19911e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
19921e1e598dSJonathan Doman             });
19933a2d0424SChris Cain         },
19943a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
19953a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
19963a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
19973a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
19983a2d0424SChris Cain }
19993a2d0424SChris Cain 
20003a2d0424SChris Cain /**
20013a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
20023a2d0424SChris Cain  * name associated with that string
20033a2d0424SChris Cain  *
20043a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20053a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
20063a2d0424SChris Cain  *
20073a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
20083a2d0424SChris Cain  */
20093a2d0424SChris Cain inline std::string
20103a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20113a2d0424SChris Cain                       const std::string& modeString)
20123a2d0424SChris Cain {
20133a2d0424SChris Cain     std::string mode;
20143a2d0424SChris Cain 
20153a2d0424SChris Cain     if (modeString == "Static")
20163a2d0424SChris Cain     {
20173a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
20183a2d0424SChris Cain     }
20193a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
20203a2d0424SChris Cain     {
20210fda0f12SGeorge Liu         mode =
20220fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
20233a2d0424SChris Cain     }
20243a2d0424SChris Cain     else if (modeString == "PowerSaving")
20253a2d0424SChris Cain     {
20263a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
20273a2d0424SChris Cain     }
20283a2d0424SChris Cain     else
20293a2d0424SChris Cain     {
20303a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
20313a2d0424SChris Cain     }
20323a2d0424SChris Cain     return mode;
20333a2d0424SChris Cain }
20343a2d0424SChris Cain 
20353a2d0424SChris Cain /**
20363a2d0424SChris Cain  * @brief Sets system power mode.
20373a2d0424SChris Cain  *
20383a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
20393a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
20403a2d0424SChris Cain  *
20413a2d0424SChris Cain  * @return None.
20423a2d0424SChris Cain  */
20433a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20443a2d0424SChris Cain                          const std::string& pmode)
20453a2d0424SChris Cain {
20463a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
20473a2d0424SChris Cain 
20483a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
20493a2d0424SChris Cain     if (powerMode.empty())
20503a2d0424SChris Cain     {
20513a2d0424SChris Cain         return;
20523a2d0424SChris Cain     }
20533a2d0424SChris Cain 
20543a2d0424SChris Cain     // Get Power Mode object path:
20553a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
2056b9d36b47SEd Tanous         [aResp,
2057b9d36b47SEd Tanous          powerMode](const boost::system::error_code ec,
2058b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
20593a2d0424SChris Cain         if (ec)
20603a2d0424SChris Cain         {
2061002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2062002d39b4SEd Tanous                              << ec;
20633a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
20643a2d0424SChris Cain             messages::internalError(aResp->res);
20653a2d0424SChris Cain             return;
20663a2d0424SChris Cain         }
20673a2d0424SChris Cain         if (subtree.empty())
20683a2d0424SChris Cain         {
20693a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
20703a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
20713a2d0424SChris Cain                                        "PowerMode");
20723a2d0424SChris Cain             return;
20733a2d0424SChris Cain         }
20743a2d0424SChris Cain         if (subtree.size() > 1)
20753a2d0424SChris Cain         {
20763a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
20773a2d0424SChris Cain             // error
20783a2d0424SChris Cain             BMCWEB_LOG_DEBUG
20793a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
20803a2d0424SChris Cain                 << subtree.size();
20813a2d0424SChris Cain             messages::internalError(aResp->res);
20823a2d0424SChris Cain             return;
20833a2d0424SChris Cain         }
20843a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
20853a2d0424SChris Cain         {
20863a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
20873a2d0424SChris Cain             messages::internalError(aResp->res);
20883a2d0424SChris Cain             return;
20893a2d0424SChris Cain         }
20903a2d0424SChris Cain         const std::string& path = subtree[0].first;
20913a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
20923a2d0424SChris Cain         if (service.empty())
20933a2d0424SChris Cain         {
20943a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20953a2d0424SChris Cain             messages::internalError(aResp->res);
20963a2d0424SChris Cain             return;
20973a2d0424SChris Cain         }
20983a2d0424SChris Cain 
20993a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
21003a2d0424SChris Cain                          << path;
21013a2d0424SChris Cain 
21023a2d0424SChris Cain         // Set the Power Mode property
21033a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
21048a592810SEd Tanous             [aResp](const boost::system::error_code ec2) {
21058a592810SEd Tanous             if (ec2)
21063a2d0424SChris Cain             {
21073a2d0424SChris Cain                 messages::internalError(aResp->res);
21083a2d0424SChris Cain                 return;
21093a2d0424SChris Cain             }
21103a2d0424SChris Cain             },
21113a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
21123a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2113168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
21143a2d0424SChris Cain         },
21153a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
21163a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
21173a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
21183a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
21193a2d0424SChris Cain }
21203a2d0424SChris Cain 
21213a2d0424SChris Cain /**
212251709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
212351709ffdSYong Li  *
212451709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
212551709ffdSYong Li  *
212651709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
212751709ffdSYong Li  * translation cannot be done, returns an empty string.
212851709ffdSYong Li  */
212923a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
213051709ffdSYong Li {
213151709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
213251709ffdSYong Li     {
213351709ffdSYong Li         return "None";
213451709ffdSYong Li     }
21353174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
213651709ffdSYong Li     {
213751709ffdSYong Li         return "ResetSystem";
213851709ffdSYong Li     }
21393174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
214051709ffdSYong Li     {
214151709ffdSYong Li         return "PowerDown";
214251709ffdSYong Li     }
21433174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
214451709ffdSYong Li     {
214551709ffdSYong Li         return "PowerCycle";
214651709ffdSYong Li     }
214751709ffdSYong Li 
214851709ffdSYong Li     return "";
214951709ffdSYong Li }
215051709ffdSYong Li 
215151709ffdSYong Li /**
2152c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2153c45f0082SYong Li  *
2154c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2155c45f0082SYong Li  *
2156c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2157c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2158c45f0082SYong Li  */
2159c45f0082SYong Li 
216023a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2161c45f0082SYong Li {
2162c45f0082SYong Li     if (rfAction == "None")
2163c45f0082SYong Li     {
2164c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2165c45f0082SYong Li     }
21663174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2167c45f0082SYong Li     {
2168c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2169c45f0082SYong Li     }
21703174e4dfSEd Tanous     if (rfAction == "PowerDown")
2171c45f0082SYong Li     {
2172c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2173c45f0082SYong Li     }
21743174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2175c45f0082SYong Li     {
2176c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2177c45f0082SYong Li     }
2178c45f0082SYong Li 
2179c45f0082SYong Li     return "";
2180c45f0082SYong Li }
2181c45f0082SYong Li 
2182c45f0082SYong Li /**
218351709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
218451709ffdSYong Li  *
218551709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
218651709ffdSYong Li  *
218751709ffdSYong Li  * @return None.
218851709ffdSYong Li  */
21898d1b46d7Szhanghch05 inline void
21908d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
219151709ffdSYong Li {
219251709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2193bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2194bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2195bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2196bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
219751709ffdSYong Li         [aResp](const boost::system::error_code ec,
2198b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
219951709ffdSYong Li         if (ec)
220051709ffdSYong Li         {
220151709ffdSYong Li             // watchdog service is stopped
220251709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
220351709ffdSYong Li             return;
220451709ffdSYong Li         }
220551709ffdSYong Li 
220651709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
220751709ffdSYong Li 
220851709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
220951709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
221051709ffdSYong Li 
221151709ffdSYong Li         // watchdog service is running/enabled
221251709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
221351709ffdSYong Li 
2214bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2215bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
221651709ffdSYong Li 
2217bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2218bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2219bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2220bc1d29deSKrzysztof Grobelny 
2221bc1d29deSKrzysztof Grobelny         if (!success)
222251709ffdSYong Li         {
222351709ffdSYong Li             messages::internalError(aResp->res);
2224601af5edSChicago Duan             return;
222551709ffdSYong Li         }
222651709ffdSYong Li 
2227bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
222851709ffdSYong Li         {
2229bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
223051709ffdSYong Li         }
223151709ffdSYong Li 
2232bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2233bc1d29deSKrzysztof Grobelny         {
2234bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
223551709ffdSYong Li             if (action.empty())
223651709ffdSYong Li             {
223751709ffdSYong Li                 messages::internalError(aResp->res);
2238601af5edSChicago Duan                 return;
223951709ffdSYong Li             }
224051709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
224151709ffdSYong Li         }
2242bc1d29deSKrzysztof Grobelny         });
224351709ffdSYong Li }
224451709ffdSYong Li 
224551709ffdSYong Li /**
2246c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2247c45f0082SYong Li  *
2248c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2249c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2250c45f0082SYong Li  *                       RF request.
2251c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2252c45f0082SYong Li  *
2253c45f0082SYong Li  * @return None.
2254c45f0082SYong Li  */
22558d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2256c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2257c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2258c45f0082SYong Li {
2259c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2260c45f0082SYong Li 
2261c45f0082SYong Li     if (wdtTimeOutAction)
2262c45f0082SYong Li     {
2263c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2264c45f0082SYong Li         // check if TimeOut Action is Valid
2265c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2266c45f0082SYong Li         {
2267c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2268c45f0082SYong Li                              << *wdtTimeOutAction;
2269c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2270c45f0082SYong Li                                              "TimeoutAction");
2271c45f0082SYong Li             return;
2272c45f0082SYong Li         }
2273c45f0082SYong Li 
2274c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2275c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2276c45f0082SYong Li             if (ec)
2277c45f0082SYong Li             {
2278c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2279c45f0082SYong Li                 messages::internalError(aResp->res);
2280c45f0082SYong Li                 return;
2281c45f0082SYong Li             }
2282c45f0082SYong Li             },
2283c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2284c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2285c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2286c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2287168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2288c45f0082SYong Li     }
2289c45f0082SYong Li 
2290c45f0082SYong Li     if (wdtEnable)
2291c45f0082SYong Li     {
2292c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2293c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2294c45f0082SYong Li             if (ec)
2295c45f0082SYong Li             {
2296c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2297c45f0082SYong Li                 messages::internalError(aResp->res);
2298c45f0082SYong Li                 return;
2299c45f0082SYong Li             }
2300c45f0082SYong Li             },
2301c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2302c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2303c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2304c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2305168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2306c45f0082SYong Li     }
2307c45f0082SYong Li }
2308c45f0082SYong Li 
230937bbf98cSChris Cain /**
231037bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
231137bbf98cSChris Cain  *
231237bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
231337bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
231437bbf98cSChris Cain  *
231537bbf98cSChris Cain  * @return true if successful
231637bbf98cSChris Cain  */
23171e5b7c88SJiaqing Zhao inline bool
23181e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
23191e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
232037bbf98cSChris Cain {
2321bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2322bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2323bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2324bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2325bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2326bc1d29deSKrzysztof Grobelny 
2327bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2328bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2329bc1d29deSKrzysztof Grobelny         "EnterUtilizationPercent", enterUtilizationPercent,
2330bc1d29deSKrzysztof Grobelny         "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime",
2331bc1d29deSKrzysztof Grobelny         exitDwellTime);
2332bc1d29deSKrzysztof Grobelny 
2333bc1d29deSKrzysztof Grobelny     if (!success)
233437bbf98cSChris Cain     {
233537bbf98cSChris Cain         return false;
233637bbf98cSChris Cain     }
2337bc1d29deSKrzysztof Grobelny 
2338bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
233937bbf98cSChris Cain     {
2340bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
234137bbf98cSChris Cain     }
2342bc1d29deSKrzysztof Grobelny 
2343bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
234437bbf98cSChris Cain     {
2345bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2346bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
234737bbf98cSChris Cain     }
2348bc1d29deSKrzysztof Grobelny 
2349bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2350bc1d29deSKrzysztof Grobelny     {
2351bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
235237bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
235337bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
235437bbf98cSChris Cain                 .count();
235537bbf98cSChris Cain     }
2356bc1d29deSKrzysztof Grobelny 
2357bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
235837bbf98cSChris Cain     {
2359bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2360bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
236137bbf98cSChris Cain     }
2362bc1d29deSKrzysztof Grobelny 
2363bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
236437bbf98cSChris Cain     {
2365bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
236637bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
236737bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
236837bbf98cSChris Cain                 .count();
236937bbf98cSChris Cain     }
237037bbf98cSChris Cain 
237137bbf98cSChris Cain     return true;
237237bbf98cSChris Cain }
237337bbf98cSChris Cain 
237437bbf98cSChris Cain /**
237537bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
237637bbf98cSChris Cain  *
237737bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
237837bbf98cSChris Cain  *
237937bbf98cSChris Cain  * @return None.
238037bbf98cSChris Cain  */
238137bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
238237bbf98cSChris Cain {
238337bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
238437bbf98cSChris Cain 
238537bbf98cSChris Cain     // Get IdlePowerSaver object path:
238637bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
2387b9d36b47SEd Tanous         [aResp](const boost::system::error_code ec,
2388b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
238937bbf98cSChris Cain         if (ec)
239037bbf98cSChris Cain         {
239137bbf98cSChris Cain             BMCWEB_LOG_DEBUG
239237bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
239337bbf98cSChris Cain                 << ec;
239437bbf98cSChris Cain             messages::internalError(aResp->res);
239537bbf98cSChris Cain             return;
239637bbf98cSChris Cain         }
239737bbf98cSChris Cain         if (subtree.empty())
239837bbf98cSChris Cain         {
239937bbf98cSChris Cain             // This is an optional interface so just return
240037bbf98cSChris Cain             // if there is no instance found
240137bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
240237bbf98cSChris Cain             return;
240337bbf98cSChris Cain         }
240437bbf98cSChris Cain         if (subtree.size() > 1)
240537bbf98cSChris Cain         {
240637bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
240737bbf98cSChris Cain             // is an error
240837bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
240937bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
241037bbf98cSChris Cain                              << subtree.size();
241137bbf98cSChris Cain             messages::internalError(aResp->res);
241237bbf98cSChris Cain             return;
241337bbf98cSChris Cain         }
241437bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
241537bbf98cSChris Cain         {
241637bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
241737bbf98cSChris Cain             messages::internalError(aResp->res);
241837bbf98cSChris Cain             return;
241937bbf98cSChris Cain         }
242037bbf98cSChris Cain         const std::string& path = subtree[0].first;
242137bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
242237bbf98cSChris Cain         if (service.empty())
242337bbf98cSChris Cain         {
2424002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
242537bbf98cSChris Cain             messages::internalError(aResp->res);
242637bbf98cSChris Cain             return;
242737bbf98cSChris Cain         }
242837bbf98cSChris Cain 
242937bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2430bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2431bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2432bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
24338a592810SEd Tanous             [aResp](const boost::system::error_code ec2,
24341e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
24358a592810SEd Tanous             if (ec2)
243637bbf98cSChris Cain             {
243737bbf98cSChris Cain                 BMCWEB_LOG_ERROR
24388a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
243937bbf98cSChris Cain                 messages::internalError(aResp->res);
244037bbf98cSChris Cain                 return;
244137bbf98cSChris Cain             }
244237bbf98cSChris Cain 
2443e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
244437bbf98cSChris Cain             {
244537bbf98cSChris Cain                 messages::internalError(aResp->res);
244637bbf98cSChris Cain                 return;
244737bbf98cSChris Cain             }
2448bc1d29deSKrzysztof Grobelny             });
244937bbf98cSChris Cain         },
245037bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
245137bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
245237bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
245337bbf98cSChris Cain         std::array<const char*, 1>{
245437bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
245537bbf98cSChris Cain 
245637bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
245737bbf98cSChris Cain }
245837bbf98cSChris Cain 
245937bbf98cSChris Cain /**
246037bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
246137bbf98cSChris Cain  *
246237bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
246337bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
246437bbf98cSChris Cain  *                       RF request.
246537bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
246637bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
246737bbf98cSChris Cain  * before entering idle state.
246837bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
246937bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
247037bbf98cSChris Cain  * before exiting idle state
247137bbf98cSChris Cain  *
247237bbf98cSChris Cain  * @return None.
247337bbf98cSChris Cain  */
247437bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
247537bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
247637bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
247737bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
247837bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
247937bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
248037bbf98cSChris Cain {
248137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
248237bbf98cSChris Cain 
248337bbf98cSChris Cain     // Get IdlePowerSaver object path:
248437bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
248537bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2486b9d36b47SEd Tanous          ipsExitTime](const boost::system::error_code ec,
2487b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
248837bbf98cSChris Cain         if (ec)
248937bbf98cSChris Cain         {
249037bbf98cSChris Cain             BMCWEB_LOG_DEBUG
249137bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
249237bbf98cSChris Cain                 << ec;
249337bbf98cSChris Cain             messages::internalError(aResp->res);
249437bbf98cSChris Cain             return;
249537bbf98cSChris Cain         }
249637bbf98cSChris Cain         if (subtree.empty())
249737bbf98cSChris Cain         {
249837bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
249937bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
250037bbf98cSChris Cain                                        "IdlePowerSaver");
250137bbf98cSChris Cain             return;
250237bbf98cSChris Cain         }
250337bbf98cSChris Cain         if (subtree.size() > 1)
250437bbf98cSChris Cain         {
250537bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
250637bbf98cSChris Cain             // is an error
25070fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
25080fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
250937bbf98cSChris Cain                 << subtree.size();
251037bbf98cSChris Cain             messages::internalError(aResp->res);
251137bbf98cSChris Cain             return;
251237bbf98cSChris Cain         }
251337bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
251437bbf98cSChris Cain         {
251537bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
251637bbf98cSChris Cain             messages::internalError(aResp->res);
251737bbf98cSChris Cain             return;
251837bbf98cSChris Cain         }
251937bbf98cSChris Cain         const std::string& path = subtree[0].first;
252037bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
252137bbf98cSChris Cain         if (service.empty())
252237bbf98cSChris Cain         {
2523002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
252437bbf98cSChris Cain             messages::internalError(aResp->res);
252537bbf98cSChris Cain             return;
252637bbf98cSChris Cain         }
252737bbf98cSChris Cain 
252837bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
252937bbf98cSChris Cain         // need to be updated
253037bbf98cSChris Cain 
253137bbf98cSChris Cain         if (ipsEnable)
253237bbf98cSChris Cain         {
253337bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25348a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25358a592810SEd Tanous                 if (ec2)
253637bbf98cSChris Cain                 {
25378a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
253837bbf98cSChris Cain                     messages::internalError(aResp->res);
253937bbf98cSChris Cain                     return;
254037bbf98cSChris Cain                 }
254137bbf98cSChris Cain                 },
254237bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2543002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2544002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
254537bbf98cSChris Cain         }
254637bbf98cSChris Cain         if (ipsEnterUtil)
254737bbf98cSChris Cain         {
254837bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25498a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25508a592810SEd Tanous                 if (ec2)
255137bbf98cSChris Cain                 {
25528a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
255337bbf98cSChris Cain                     messages::internalError(aResp->res);
255437bbf98cSChris Cain                     return;
255537bbf98cSChris Cain                 }
255637bbf98cSChris Cain                 },
255737bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
255837bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
255937bbf98cSChris Cain                 "EnterUtilizationPercent",
2560168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
256137bbf98cSChris Cain         }
256237bbf98cSChris Cain         if (ipsEnterTime)
256337bbf98cSChris Cain         {
256437bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
256537bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
256637bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25678a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25688a592810SEd Tanous                 if (ec2)
256937bbf98cSChris Cain                 {
25708a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
257137bbf98cSChris Cain                     messages::internalError(aResp->res);
257237bbf98cSChris Cain                     return;
257337bbf98cSChris Cain                 }
257437bbf98cSChris Cain                 },
257537bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
257637bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2577168e20c1SEd Tanous                 "EnterDwellTime",
2578168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
257937bbf98cSChris Cain         }
258037bbf98cSChris Cain         if (ipsExitUtil)
258137bbf98cSChris Cain         {
258237bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
25838a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
25848a592810SEd Tanous                 if (ec2)
258537bbf98cSChris Cain                 {
25868a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
258737bbf98cSChris Cain                     messages::internalError(aResp->res);
258837bbf98cSChris Cain                     return;
258937bbf98cSChris Cain                 }
259037bbf98cSChris Cain                 },
259137bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
259237bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
259337bbf98cSChris Cain                 "ExitUtilizationPercent",
2594168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
259537bbf98cSChris Cain         }
259637bbf98cSChris Cain         if (ipsExitTime)
259737bbf98cSChris Cain         {
259837bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
259937bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
260037bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26018a592810SEd Tanous                 [aResp](const boost::system::error_code ec2) {
26028a592810SEd Tanous                 if (ec2)
260337bbf98cSChris Cain                 {
26048a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
260537bbf98cSChris Cain                     messages::internalError(aResp->res);
260637bbf98cSChris Cain                     return;
260737bbf98cSChris Cain                 }
260837bbf98cSChris Cain                 },
260937bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
261037bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2611168e20c1SEd Tanous                 "ExitDwellTime",
2612168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
261337bbf98cSChris Cain         }
261437bbf98cSChris Cain         },
261537bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
261637bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
261737bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
261837bbf98cSChris Cain         std::array<const char*, 1>{
261937bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
262037bbf98cSChris Cain 
262137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
262237bbf98cSChris Cain }
262337bbf98cSChris Cain 
2624dd60b9edSEd Tanous inline void handleComputerSystemHead(
2625dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2626dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2627dd60b9edSEd Tanous {
2628dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2629dd60b9edSEd Tanous     {
2630dd60b9edSEd Tanous         return;
2631dd60b9edSEd Tanous     }
2632dd60b9edSEd Tanous     asyncResp->res.addHeader(
2633dd60b9edSEd Tanous         boost::beast::http::field::link,
2634dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2635dd60b9edSEd Tanous }
2636dd60b9edSEd Tanous 
2637c45f0082SYong Li /**
2638c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2639c5b2abe0SLewanczyk, Dawid  * Schema
2640c5b2abe0SLewanczyk, Dawid  */
26417e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
26421abe55efSEd Tanous {
26437e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2644dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2645dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2646dd60b9edSEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
2647dd60b9edSEd Tanous 
2648dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2649ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
26507e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2651f4c99e70SEd Tanous             [&app](const crow::Request& req,
26527e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
26533ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2654f4c99e70SEd Tanous         {
2655f4c99e70SEd Tanous             return;
2656f4c99e70SEd Tanous         }
2657dd60b9edSEd Tanous 
2658dd60b9edSEd Tanous         asyncResp->res.addHeader(
2659dd60b9edSEd Tanous             boost::beast::http::field::link,
2660dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
26618d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
26620f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
26638d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
26648d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2665462023adSSunitha Harish 
26661e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2667002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
26681e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2669002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
26708a592810SEd Tanous             [asyncResp](const boost::system::error_code ec2,
26711e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2672002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
26732c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2674002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
26751476687dSEd Tanous 
26761476687dSEd Tanous             nlohmann::json::object_t system;
26771476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
26781476687dSEd Tanous             ifaceArray.push_back(std::move(system));
267994bda602STim Lee             count = ifaceArray.size();
26808a592810SEd Tanous             if (!ec2)
2681462023adSSunitha Harish             {
2682462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
26831476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2684002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
26851476687dSEd Tanous                 ifaceArray.push_back(std::move(hypervisor));
26862c70f800SEd Tanous                 count = ifaceArray.size();
2687cb13a392SEd Tanous             }
26881e1e598dSJonathan Doman             });
26897e860f15SJohn Edward Broadbent         });
2690c5b2abe0SLewanczyk, Dawid }
26917e860f15SJohn Edward Broadbent 
26927e860f15SJohn Edward Broadbent /**
26937e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
26947e860f15SJohn Edward Broadbent  */
26954f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
26967e860f15SJohn Edward Broadbent {
26977e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
26987e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
26997e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
27007e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
27017e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
27027e860f15SJohn Edward Broadbent 
27037e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
27047e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
27057e860f15SJohn Edward Broadbent         if (ec)
27067e860f15SJohn Edward Broadbent         {
27077e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
27087e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
27097e860f15SJohn Edward Broadbent             return;
27107e860f15SJohn Edward Broadbent         }
27117e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
27127e860f15SJohn Edward Broadbent         },
27137e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
27147e860f15SJohn Edward Broadbent }
2715c5b2abe0SLewanczyk, Dawid 
2716c5b2abe0SLewanczyk, Dawid /**
2717cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2718cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2719cc340dd9SEd Tanous  */
27207e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2721cc340dd9SEd Tanous {
2722cc340dd9SEd Tanous     /**
2723cc340dd9SEd Tanous      * Function handles POST method request.
2724cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2725cc340dd9SEd Tanous      */
27267e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
27277e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2728ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2729002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2730002d39b4SEd Tanous             [&app](const crow::Request& req,
27317e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27323ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
273345ca1b86SEd Tanous         {
273445ca1b86SEd Tanous             return;
273545ca1b86SEd Tanous         }
27369712f8acSEd Tanous         std::string resetType;
273715ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
27387e860f15SJohn Edward Broadbent                                        resetType))
2739cc340dd9SEd Tanous         {
2740cc340dd9SEd Tanous             return;
2741cc340dd9SEd Tanous         }
2742cc340dd9SEd Tanous 
2743d22c8396SJason M. Bills         // Get the command and host vs. chassis
2744cc340dd9SEd Tanous         std::string command;
2745543f4400SEd Tanous         bool hostCommand = true;
2746d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2747cc340dd9SEd Tanous         {
2748cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2749d22c8396SJason M. Bills             hostCommand = true;
2750d22c8396SJason M. Bills         }
2751d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2752d22c8396SJason M. Bills         {
2753d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2754d22c8396SJason M. Bills             hostCommand = false;
2755d22c8396SJason M. Bills         }
2756d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2757d22c8396SJason M. Bills         {
275886a0851aSJason M. Bills             command =
275986a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
276086a0851aSJason M. Bills             hostCommand = true;
2761cc340dd9SEd Tanous         }
27629712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2763cc340dd9SEd Tanous         {
2764cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2765d22c8396SJason M. Bills             hostCommand = true;
2766cc340dd9SEd Tanous         }
27679712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2768cc340dd9SEd Tanous         {
27690fda0f12SGeorge Liu             command =
27700fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2771d22c8396SJason M. Bills             hostCommand = true;
2772d22c8396SJason M. Bills         }
2773d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2774d22c8396SJason M. Bills         {
277586a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
277686a0851aSJason M. Bills             hostCommand = true;
2777cc340dd9SEd Tanous         }
2778bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2779bfd5b826SLakshminarayana R. Kammath         {
2780bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2781bfd5b826SLakshminarayana R. Kammath             return;
2782bfd5b826SLakshminarayana R. Kammath         }
2783cc340dd9SEd Tanous         else
2784cc340dd9SEd Tanous         {
27858d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
27868d1b46d7Szhanghch05                                              resetType);
2787cc340dd9SEd Tanous             return;
2788cc340dd9SEd Tanous         }
2789cc340dd9SEd Tanous 
2790d22c8396SJason M. Bills         if (hostCommand)
2791d22c8396SJason M. Bills         {
2792cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
2793d22c8396SJason M. Bills                 [asyncResp, resetType](const boost::system::error_code ec) {
2794cc340dd9SEd Tanous                 if (ec)
2795cc340dd9SEd Tanous                 {
2796cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2797002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2798d22c8396SJason M. Bills                     {
2799d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2800d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2801d22c8396SJason M. Bills                     }
2802d22c8396SJason M. Bills                     else
2803d22c8396SJason M. Bills                     {
2804f12894f8SJason M. Bills                         messages::internalError(asyncResp->res);
2805d22c8396SJason M. Bills                     }
2806cc340dd9SEd Tanous                     return;
2807cc340dd9SEd Tanous                 }
2808f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2809cc340dd9SEd Tanous                 },
2810cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2811cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2812cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
28139712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2814168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2815cc340dd9SEd Tanous         }
2816d22c8396SJason M. Bills         else
2817d22c8396SJason M. Bills         {
2818d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
2819d22c8396SJason M. Bills                 [asyncResp, resetType](const boost::system::error_code ec) {
2820d22c8396SJason M. Bills                 if (ec)
2821d22c8396SJason M. Bills                 {
2822d22c8396SJason M. Bills                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2823002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2824d22c8396SJason M. Bills                     {
2825d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2826d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2827d22c8396SJason M. Bills                     }
2828d22c8396SJason M. Bills                     else
2829d22c8396SJason M. Bills                     {
2830d22c8396SJason M. Bills                         messages::internalError(asyncResp->res);
2831d22c8396SJason M. Bills                     }
2832d22c8396SJason M. Bills                     return;
2833d22c8396SJason M. Bills                 }
2834d22c8396SJason M. Bills                 messages::success(asyncResp->res);
2835d22c8396SJason M. Bills                 },
2836d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
2837d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
2838d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
2839002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2840168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2841d22c8396SJason M. Bills         }
28427e860f15SJohn Edward Broadbent         });
2843d22c8396SJason M. Bills }
2844cc340dd9SEd Tanous 
2845*38c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead(
2846dd60b9edSEd Tanous     App& app, const crow::Request& req,
2847dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2848dd60b9edSEd Tanous {
2849dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2850dd60b9edSEd Tanous     {
2851dd60b9edSEd Tanous         return;
2852dd60b9edSEd Tanous     }
2853dd60b9edSEd Tanous 
2854dd60b9edSEd Tanous     asyncResp->res.addHeader(
2855dd60b9edSEd Tanous         boost::beast::http::field::link,
2856dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2857dd60b9edSEd Tanous }
2858dd60b9edSEd Tanous 
2859cc340dd9SEd Tanous /**
28606617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2861c5b2abe0SLewanczyk, Dawid  */
28627e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
28631abe55efSEd Tanous {
2864c5b2abe0SLewanczyk, Dawid 
2865dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2866dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystem)
2867dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2868dd60b9edSEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
2869c5b2abe0SLewanczyk, Dawid     /**
2870c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2871c5b2abe0SLewanczyk, Dawid      */
28727e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2873ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
2874002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
2875002d39b4SEd Tanous             [&app](const crow::Request& req,
2876002d39b4SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28773ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
287845ca1b86SEd Tanous         {
287945ca1b86SEd Tanous             return;
288045ca1b86SEd Tanous         }
2881dd60b9edSEd Tanous         asyncResp->res.addHeader(
2882dd60b9edSEd Tanous             boost::beast::http::field::link,
2883dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
28848d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
288537bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
28868d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
28878d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
28888d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
28898d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
28908d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
28918d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
28928d1b46d7Szhanghch05             "Disabled";
28938d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
28948d1b46d7Szhanghch05             uint64_t(0);
28958d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
28968d1b46d7Szhanghch05             "Disabled";
2897002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
289804a258f4SEd Tanous 
28991476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
29001476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
29011476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
29021476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
29031476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
29041476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
2905029573d4SEd Tanous 
2906002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
29071476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
29081476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
29091476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
29101476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
2911c5b2abe0SLewanczyk, Dawid 
29121476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
29131476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
29141476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
29151476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
2916c4bf6374SJason M. Bills 
29171476687dSEd Tanous         nlohmann::json::array_t managedBy;
29181476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
29191476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
2920002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
29211476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
29221476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
29230e8ac5e7SGunnar Mills 
29240e8ac5e7SGunnar Mills         // Fill in SerialConsole info
2925002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
2926002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
2927002d39b4SEd Tanous             true;
29281476687dSEd Tanous 
29290e8ac5e7SGunnar Mills         // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
29301476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
29311476687dSEd Tanous             true;
29321476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
29331476687dSEd Tanous         asyncResp->res
29341476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
29351476687dSEd Tanous             "Press ~. to exit console";
29360e8ac5e7SGunnar Mills 
29370e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
29380e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
2939002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
2940002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
2941002d39b4SEd Tanous             4;
29421476687dSEd Tanous         asyncResp->res
2943002d39b4SEd Tanous             .jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = {"KVMIP"};
29441476687dSEd Tanous 
29450e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
2946e284a7c1SJames Feist         constexpr const std::array<const char*, 4> inventoryForSystems = {
2947b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
29482ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
2949e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
2950e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
2951b49ac873SJames Feist 
2952b49ac873SJames Feist         auto health = std::make_shared<HealthPopulate>(asyncResp);
2953b49ac873SJames Feist         crow::connections::systemBus->async_method_call(
2954b49ac873SJames Feist             [health](const boost::system::error_code ec,
2955914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
2956b49ac873SJames Feist             if (ec)
2957b49ac873SJames Feist             {
2958b49ac873SJames Feist                 // no inventory
2959b49ac873SJames Feist                 return;
2960b49ac873SJames Feist             }
2961b49ac873SJames Feist 
2962914e2d5dSEd Tanous             health->inventory = resp;
2963b49ac873SJames Feist             },
2964b49ac873SJames Feist             "xyz.openbmc_project.ObjectMapper",
2965b49ac873SJames Feist             "/xyz/openbmc_project/object_mapper",
2966b49ac873SJames Feist             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2967b49ac873SJames Feist             int32_t(0), inventoryForSystems);
2968b49ac873SJames Feist 
2969b49ac873SJames Feist         health->populate();
2970b49ac873SJames Feist 
2971002d39b4SEd Tanous         getMainChassisId(asyncResp,
2972002d39b4SEd Tanous                          [](const std::string& chassisId,
29738d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2974b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
2975b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
2976b2c7e208SEd Tanous             chassis["@odata.id"] = "/redfish/v1/Chassis/" + chassisId;
2977002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
2978c5d03ff4SJennifer Lee         });
2979a3002228SAppaRao Puli 
29809f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
29819f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
2982a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
29835bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
29846c34de48SEd Tanous         getHostState(asyncResp);
2985491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
2986978b8803SAndrew Geissler         getBootProgress(asyncResp);
2987adbe192aSJason M. Bills         getPCIeDeviceList(asyncResp, "PCIeDevices");
298851709ffdSYong Li         getHostWatchdogTimer(asyncResp);
2989c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
29906bd5a8d2SGunnar Mills         getAutomaticRetry(asyncResp);
2991c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
2992a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2993a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
2994a6349918SAppaRao Puli #endif
29951981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
29963a2d0424SChris Cain         getPowerMode(asyncResp);
299737bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
29987e860f15SJohn Edward Broadbent         });
2999550a6bf8SJiaqing Zhao 
30007e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3001ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
30027e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
300345ca1b86SEd Tanous             [&app](const crow::Request& req,
30047e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
30053ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
300645ca1b86SEd Tanous         {
300745ca1b86SEd Tanous             return;
300845ca1b86SEd Tanous         }
3009dd60b9edSEd Tanous         asyncResp->res.addHeader(
3010dd60b9edSEd Tanous             boost::beast::http::field::link,
3011dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3012dd60b9edSEd Tanous 
30139f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
3014cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
301598e386ecSGunnar Mills         std::optional<std::string> assetTag;
3016c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
30173a2d0424SChris Cain         std::optional<std::string> powerMode;
3018550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
3019550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
3020550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
3021550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
3022550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
3023550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
3024550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
3025550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
3026550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
3027550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
3028550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
3029550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
3030550a6bf8SJiaqing Zhao 
3031550a6bf8SJiaqing Zhao         // clang-format off
303215ed6780SWilly Tu         if (!json_util::readJsonPatch(
3033550a6bf8SJiaqing Zhao                 req, asyncResp->res,
3034550a6bf8SJiaqing Zhao                 "IndicatorLED", indicatorLed,
30357e860f15SJohn Edward Broadbent                 "LocationIndicatorActive", locationIndicatorActive,
3036550a6bf8SJiaqing Zhao                 "AssetTag", assetTag,
3037550a6bf8SJiaqing Zhao                 "PowerRestorePolicy", powerRestorePolicy,
3038550a6bf8SJiaqing Zhao                 "PowerMode", powerMode,
3039550a6bf8SJiaqing Zhao                 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3040550a6bf8SJiaqing Zhao                 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3041550a6bf8SJiaqing Zhao                 "Boot/BootSourceOverrideTarget", bootSource,
3042550a6bf8SJiaqing Zhao                 "Boot/BootSourceOverrideMode", bootType,
3043550a6bf8SJiaqing Zhao                 "Boot/BootSourceOverrideEnabled", bootEnable,
3044550a6bf8SJiaqing Zhao                 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3045550a6bf8SJiaqing Zhao                 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3046550a6bf8SJiaqing Zhao                 "IdlePowerSaver/Enabled", ipsEnable,
3047550a6bf8SJiaqing Zhao                 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3048550a6bf8SJiaqing Zhao                 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3049550a6bf8SJiaqing Zhao                 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3050550a6bf8SJiaqing Zhao                 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
30516617338dSEd Tanous         {
30526617338dSEd Tanous             return;
30536617338dSEd Tanous         }
3054550a6bf8SJiaqing Zhao         // clang-format on
3055491d8ee7SSantosh Puranik 
30568d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3057c45f0082SYong Li 
305898e386ecSGunnar Mills         if (assetTag)
305998e386ecSGunnar Mills         {
306098e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
306198e386ecSGunnar Mills         }
306298e386ecSGunnar Mills 
3063550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3064c45f0082SYong Li         {
3065f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3066c45f0082SYong Li         }
3067c45f0082SYong Li 
3068cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
306969f35306SGunnar Mills         {
3070002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3071491d8ee7SSantosh Puranik         }
3072550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
307369f35306SGunnar Mills         {
3074550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
307569f35306SGunnar Mills         }
3076ac7e1e0bSAli Ahmed 
3077550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3078ac7e1e0bSAli Ahmed         {
3079550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3080550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
308169f35306SGunnar Mills         }
3082265c1602SJohnathan Mantey 
30839f8bfa7cSGunnar Mills         if (locationIndicatorActive)
30849f8bfa7cSGunnar Mills         {
3085002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
30869f8bfa7cSGunnar Mills         }
30879f8bfa7cSGunnar Mills 
30887e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
30897e860f15SJohn Edward Broadbent         // passed
30909712f8acSEd Tanous         if (indicatorLed)
30916617338dSEd Tanous         {
3092f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3093002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3094d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3095d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
30966617338dSEd Tanous         }
3097c6a620f2SGeorge Liu 
3098c6a620f2SGeorge Liu         if (powerRestorePolicy)
3099c6a620f2SGeorge Liu         {
31004e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3101c6a620f2SGeorge Liu         }
31023a2d0424SChris Cain 
31033a2d0424SChris Cain         if (powerMode)
31043a2d0424SChris Cain         {
31053a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
31063a2d0424SChris Cain         }
310737bbf98cSChris Cain 
3108550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3109550a6bf8SJiaqing Zhao             ipsExitTime)
311037bbf98cSChris Cain         {
3111002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3112002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
311337bbf98cSChris Cain         }
31147e860f15SJohn Edward Broadbent         });
3115c5b2abe0SLewanczyk, Dawid }
31161cb1a9e6SAppaRao Puli 
3117*38c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3118dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
3119dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3120dd60b9edSEd Tanous {
3121dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3122dd60b9edSEd Tanous     {
3123dd60b9edSEd Tanous         return;
3124dd60b9edSEd Tanous     }
3125dd60b9edSEd Tanous     asyncResp->res.addHeader(
3126dd60b9edSEd Tanous         boost::beast::http::field::link,
3127dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3128dd60b9edSEd Tanous }
3129dd60b9edSEd Tanous 
31301cb1a9e6SAppaRao Puli /**
31311cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
31321cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
31331cb1a9e6SAppaRao Puli  */
31347e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
31351cb1a9e6SAppaRao Puli {
3136dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3137dd60b9edSEd Tanous         .privileges(redfish::privileges::headActionInfo)
3138dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3139dd60b9edSEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
31401cb1a9e6SAppaRao Puli     /**
31411cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
31421cb1a9e6SAppaRao Puli      */
31437e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3144ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
31457e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
314645ca1b86SEd Tanous             [&app](const crow::Request& req,
31477e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
31483ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
314945ca1b86SEd Tanous         {
315045ca1b86SEd Tanous             return;
315145ca1b86SEd Tanous         }
3152dd60b9edSEd Tanous         asyncResp->res.addHeader(
3153dd60b9edSEd Tanous             boost::beast::http::field::link,
3154dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
31551476687dSEd Tanous 
31561476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
31571476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
31581476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
31591476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
31601476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
31611476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
31623215e700SNan Zhou 
31633215e700SNan Zhou         nlohmann::json::array_t parameters;
31643215e700SNan Zhou         nlohmann::json::object_t parameter;
31653215e700SNan Zhou 
31663215e700SNan Zhou         parameter["Name"] = "ResetType";
31673215e700SNan Zhou         parameter["Required"] = true;
31683215e700SNan Zhou         parameter["DataType"] = "String";
31693215e700SNan Zhou         nlohmann::json::array_t allowableValues;
31703215e700SNan Zhou         allowableValues.emplace_back("On");
31713215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
31723215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
31733215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
31743215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
31753215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
31763215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
31773215e700SNan Zhou         allowableValues.emplace_back("Nmi");
31783215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
31793215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
31803215e700SNan Zhou 
31813215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
31827e860f15SJohn Edward Broadbent         });
31831cb1a9e6SAppaRao Puli }
3184c5b2abe0SLewanczyk, Dawid } // namespace redfish
3185