xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision dfb2b40839d6cd6b96e4d891c46d964c8f2c930b)
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 
1813451e39SWilly Tu #include "bmcweb_config.h"
1913451e39SWilly Tu 
203ccb3adbSEd Tanous #include "app.hpp"
211e1e598dSJonathan Doman #include "dbus_singleton.hpp"
227a1dbc48SGeorge Liu #include "dbus_utility.hpp"
238d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
24b49ac873SJames Feist #include "health.hpp"
25746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
261c8fba97SJames Feist #include "led.hpp"
27f4c99e70SEd Tanous #include "query.hpp"
28c5d03ff4SJennifer Lee #include "redfish_util.hpp"
293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
313ccb3adbSEd Tanous #include "utils/json_utils.hpp"
32472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
333ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
342b82937eSEd Tanous #include "utils/time_utils.hpp"
35c5d03ff4SJennifer Lee 
36fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
379712f8acSEd Tanous #include <boost/container/flat_map.hpp>
38e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
39ef4c65b7SEd Tanous #include <boost/url/format.hpp>
401e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
41fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
42bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
431214b7e7SGunnar Mills 
447a1dbc48SGeorge Liu #include <array>
457a1dbc48SGeorge Liu #include <string_view>
46abf2add6SEd Tanous #include <variant>
47c5b2abe0SLewanczyk, Dawid 
481abe55efSEd Tanous namespace redfish
491abe55efSEd Tanous {
50c5b2abe0SLewanczyk, Dawid 
515c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
525c3e9272SAbhishek Patel     protocolToDBusForSystems{
535c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
545c3e9272SAbhishek Patel 
559d3ae10eSAlpana Kumari /**
569d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
579d3ae10eSAlpana Kumari  *
58ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
599d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
609d3ae10eSAlpana Kumari  *
619d3ae10eSAlpana Kumari  * @return None.
629d3ae10eSAlpana Kumari  */
638d1b46d7Szhanghch05 inline void
64ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
651e1e598dSJonathan Doman                          bool isDimmFunctional)
669d3ae10eSAlpana Kumari {
671e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
689d3ae10eSAlpana Kumari 
699d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
709d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
719d3ae10eSAlpana Kumari     // ENABLED.
7202cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
73ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
749d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
759d3ae10eSAlpana Kumari     {
76e05aec50SEd Tanous         if (isDimmFunctional)
779d3ae10eSAlpana Kumari         {
78ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
799d3ae10eSAlpana Kumari                 "Enabled";
809d3ae10eSAlpana Kumari         }
819d3ae10eSAlpana Kumari     }
829d3ae10eSAlpana Kumari }
839d3ae10eSAlpana Kumari 
8457e8c9beSAlpana Kumari /*
8557e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
8657e8c9beSAlpana Kumari  *        CPU Functional State
8757e8c9beSAlpana Kumari  *
88ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
8957e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9057e8c9beSAlpana Kumari  *
9157e8c9beSAlpana Kumari  * @return None.
9257e8c9beSAlpana Kumari  */
93ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
94ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
9557e8c9beSAlpana Kumari {
961e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
9757e8c9beSAlpana Kumari 
9802cad96eSEd Tanous     const nlohmann::json& prevProcState =
99ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10057e8c9beSAlpana Kumari 
10157e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10257e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10357e8c9beSAlpana Kumari     // Functional.
10457e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10557e8c9beSAlpana Kumari     {
106e05aec50SEd Tanous         if (isCpuFunctional)
10757e8c9beSAlpana Kumari         {
108ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
10957e8c9beSAlpana Kumari                 "Enabled";
11057e8c9beSAlpana Kumari         }
11157e8c9beSAlpana Kumari     }
11257e8c9beSAlpana Kumari }
11357e8c9beSAlpana Kumari 
114cf0e004cSNinad Palsule /*
115cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
116cf0e004cSNinad Palsule  *
117ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
118cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
119cf0e004cSNinad Palsule  *
120cf0e004cSNinad Palsule  * @return None.
121cf0e004cSNinad Palsule  */
122cf0e004cSNinad Palsule inline void
123ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
124cf0e004cSNinad Palsule                            bool isCpuPresent)
125cf0e004cSNinad Palsule {
126cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
127cf0e004cSNinad Palsule 
128cf0e004cSNinad Palsule     if (isCpuPresent)
129cf0e004cSNinad Palsule     {
130cf0e004cSNinad Palsule         nlohmann::json& procCount =
131ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
132cf0e004cSNinad Palsule         auto* procCountPtr =
133cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
134cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
135cf0e004cSNinad Palsule         {
136cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
137cf0e004cSNinad Palsule             *procCountPtr += 1;
138cf0e004cSNinad Palsule         }
139cf0e004cSNinad Palsule     }
140cf0e004cSNinad Palsule }
141cf0e004cSNinad Palsule 
142382d6475SAli Ahmed inline void getProcessorProperties(
143ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
144382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
145382d6475SAli Ahmed         properties)
14603fbed92SAli Ahmed {
14703fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
14803fbed92SAli Ahmed 
14903fbed92SAli Ahmed     // TODO: Get Model
15003fbed92SAli Ahmed 
151bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15203fbed92SAli Ahmed 
153bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
154bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15503fbed92SAli Ahmed 
156bc1d29deSKrzysztof Grobelny     if (!success)
15703fbed92SAli Ahmed     {
158ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15903fbed92SAli Ahmed         return;
16003fbed92SAli Ahmed     }
16103fbed92SAli Ahmed 
162bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16303fbed92SAli Ahmed     {
164bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
165ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
166bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
167bc1d29deSKrzysztof Grobelny 
168bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
169bc1d29deSKrzysztof Grobelny         {
170bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17103fbed92SAli Ahmed         }
17203fbed92SAli Ahmed         else
17303fbed92SAli Ahmed         {
174bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17503fbed92SAli Ahmed         }
17603fbed92SAli Ahmed     }
17703fbed92SAli Ahmed }
17803fbed92SAli Ahmed 
17903fbed92SAli Ahmed /*
18003fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18103fbed92SAli Ahmed  *
182ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18303fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18403fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18503fbed92SAli Ahmed  *
18603fbed92SAli Ahmed  * @return None.
18703fbed92SAli Ahmed  */
188ac106bf6SEd Tanous inline void
189ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
190ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19103fbed92SAli Ahmed {
192ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
193382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
194382d6475SAli Ahmed         if (ec3)
195382d6475SAli Ahmed         {
196382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
197382d6475SAli Ahmed             return;
198382d6475SAli Ahmed         }
199ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
200382d6475SAli Ahmed     };
201382d6475SAli Ahmed 
202cf0e004cSNinad Palsule     // Get the Presence of CPU
203cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
204cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
205cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
206cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
207cf0e004cSNinad Palsule 
2085fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
2095fd0aafbSNinad Palsule     {
2105fd0aafbSNinad Palsule         auto getCpuFunctionalState =
211ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec3,
212382d6475SAli Ahmed                         const bool cpuFunctionalCheck) {
213382d6475SAli Ahmed             if (ec3)
214382d6475SAli Ahmed             {
215382d6475SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
216382d6475SAli Ahmed                 return;
217382d6475SAli Ahmed             }
218ac106bf6SEd Tanous             modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
219382d6475SAli Ahmed         };
220382d6475SAli Ahmed 
221382d6475SAli Ahmed         // Get the Functional State
222382d6475SAli Ahmed         sdbusplus::asio::getProperty<bool>(
223382d6475SAli Ahmed             *crow::connections::systemBus, service, path,
2245fd0aafbSNinad Palsule             "xyz.openbmc_project.State.Decorator.OperationalStatus",
2255fd0aafbSNinad Palsule             "Functional", std::move(getCpuFunctionalState));
2265fd0aafbSNinad Palsule     }
227382d6475SAli Ahmed 
228bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
229bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
230bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
231ac106bf6SEd Tanous         [asyncResp, service,
2325e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
233b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
23403fbed92SAli Ahmed         if (ec2)
23503fbed92SAli Ahmed         {
23603fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
237ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23803fbed92SAli Ahmed             return;
23903fbed92SAli Ahmed         }
240ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
241bc1d29deSKrzysztof Grobelny         });
24203fbed92SAli Ahmed }
24303fbed92SAli Ahmed 
24457e8c9beSAlpana Kumari /*
245cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
246cf0e004cSNinad Palsule  *
247ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
248cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
249cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
250cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
251cf0e004cSNinad Palsule  *
252cf0e004cSNinad Palsule  * @return None.
253cf0e004cSNinad Palsule  */
254cf0e004cSNinad Palsule inline void
255ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2565fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& service,
2575fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& path,
258cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
259cf0e004cSNinad Palsule {
260cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties.";
261cf0e004cSNinad Palsule 
262cf0e004cSNinad Palsule     if (properties.empty())
263cf0e004cSNinad Palsule     {
2645fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
2655fd0aafbSNinad Palsule         {
266cf0e004cSNinad Palsule             sdbusplus::asio::getProperty<bool>(
267cf0e004cSNinad Palsule                 *crow::connections::systemBus, service, path,
268cf0e004cSNinad Palsule                 "xyz.openbmc_project.State."
269cf0e004cSNinad Palsule                 "Decorator.OperationalStatus",
270cf0e004cSNinad Palsule                 "Functional",
271ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec3,
272ac106bf6SEd Tanous                             bool dimmState) {
273cf0e004cSNinad Palsule                 if (ec3)
274cf0e004cSNinad Palsule                 {
275cf0e004cSNinad Palsule                     BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
276cf0e004cSNinad Palsule                     return;
277cf0e004cSNinad Palsule                 }
278ac106bf6SEd Tanous                 updateDimmProperties(asyncResp, dimmState);
279cf0e004cSNinad Palsule                 });
2805fd0aafbSNinad Palsule         }
281cf0e004cSNinad Palsule         return;
282cf0e004cSNinad Palsule     }
283cf0e004cSNinad Palsule 
284cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
285cf0e004cSNinad Palsule 
286cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
287cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
288cf0e004cSNinad Palsule         memorySizeInKB);
289cf0e004cSNinad Palsule 
290cf0e004cSNinad Palsule     if (!success)
291cf0e004cSNinad Palsule     {
292ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
293cf0e004cSNinad Palsule         return;
294cf0e004cSNinad Palsule     }
295cf0e004cSNinad Palsule 
296cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
297cf0e004cSNinad Palsule     {
298cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
299ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
300*dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
301cf0e004cSNinad Palsule         if (preValue == nullptr)
302cf0e004cSNinad Palsule         {
303ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
304*dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
305cf0e004cSNinad Palsule         }
306cf0e004cSNinad Palsule         else
307cf0e004cSNinad Palsule         {
308ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
309*dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
310*dfb2b408SPriyanga Ramasamy                 *preValue;
311cf0e004cSNinad Palsule         }
3125fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
3135fd0aafbSNinad Palsule         {
314ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3155fd0aafbSNinad Palsule                 "Enabled";
3165fd0aafbSNinad Palsule         }
317cf0e004cSNinad Palsule     }
318cf0e004cSNinad Palsule }
319cf0e004cSNinad Palsule 
320cf0e004cSNinad Palsule /*
321cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
322cf0e004cSNinad Palsule  *
323ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
324cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
325cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
326cf0e004cSNinad Palsule  *
327cf0e004cSNinad Palsule  * @return None.
328cf0e004cSNinad Palsule  */
329ac106bf6SEd Tanous inline void
330ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
332cf0e004cSNinad Palsule {
333cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
334cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
335cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
336ac106bf6SEd Tanous         [asyncResp, service,
337cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
338cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
339cf0e004cSNinad Palsule         if (ec2)
340cf0e004cSNinad Palsule         {
341cf0e004cSNinad Palsule             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
342ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
343cf0e004cSNinad Palsule             return;
344cf0e004cSNinad Palsule         }
345ac106bf6SEd Tanous         processMemoryProperties(asyncResp, service, path, properties);
346cf0e004cSNinad Palsule         });
347cf0e004cSNinad Palsule }
348cf0e004cSNinad Palsule 
349cf0e004cSNinad Palsule /*
350c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
351c5b2abe0SLewanczyk, Dawid  *
352ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
3538f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
354c5b2abe0SLewanczyk, Dawid  *
355c5b2abe0SLewanczyk, Dawid  * @return None.
356c5b2abe0SLewanczyk, Dawid  */
357b5a76932SEd Tanous inline void
358ac106bf6SEd Tanous     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
359b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
3601abe55efSEd Tanous {
36155c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
362e99073f5SGeorge Liu     constexpr std::array<std::string_view, 5> interfaces = {
363e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Decorator.Asset",
364e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Cpu",
365e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
366e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System",
367e99073f5SGeorge Liu         "xyz.openbmc_project.Common.UUID",
368e99073f5SGeorge Liu     };
369e99073f5SGeorge Liu     dbus::utility::getSubTree(
370e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
371ac106bf6SEd Tanous         [asyncResp,
372e99073f5SGeorge Liu          systemHealth](const boost::system::error_code& ec,
373b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
3741abe55efSEd Tanous         if (ec)
3751abe55efSEd Tanous         {
37655c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
377ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
378c5b2abe0SLewanczyk, Dawid             return;
379c5b2abe0SLewanczyk, Dawid         }
380c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
381002d39b4SEd Tanous         for (const std::pair<
382002d39b4SEd Tanous                  std::string,
383002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
3841214b7e7SGunnar Mills                  object : subtree)
3851abe55efSEd Tanous         {
386c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
38755c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
388002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
3891214b7e7SGunnar Mills                 connectionNames = object.second;
39026f6976fSEd Tanous             if (connectionNames.empty())
3911abe55efSEd Tanous             {
392c5b2abe0SLewanczyk, Dawid                 continue;
393c5b2abe0SLewanczyk, Dawid             }
394029573d4SEd Tanous 
3955fd0aafbSNinad Palsule             std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
3965fd0aafbSNinad Palsule             std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
3975bc2dc8eSJames Feist 
3985fd0aafbSNinad Palsule             if constexpr (bmcwebEnableProcMemStatus)
3995fd0aafbSNinad Palsule             {
4005fd0aafbSNinad Palsule                 memoryHealth = std::make_shared<HealthPopulate>(
401ac106bf6SEd Tanous                     asyncResp, "/MemorySummary/Status"_json_pointer);
4025fd0aafbSNinad Palsule                 systemHealth->children.emplace_back(memoryHealth);
4035bc2dc8eSJames Feist 
40413451e39SWilly Tu                 if constexpr (bmcwebEnableHealthPopulate)
40513451e39SWilly Tu                 {
4065fd0aafbSNinad Palsule                     cpuHealth = std::make_shared<HealthPopulate>(
407ac106bf6SEd Tanous                         asyncResp, "/ProcessorSummary/Status"_json_pointer);
4085fd0aafbSNinad Palsule 
4095bc2dc8eSJames Feist                     systemHealth->children.emplace_back(cpuHealth);
41013451e39SWilly Tu                 }
4115fd0aafbSNinad Palsule             }
4125bc2dc8eSJames Feist 
4136c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
4146c34de48SEd Tanous             // BiosVer
41504a258f4SEd Tanous             for (const auto& connection : connectionNames)
4161abe55efSEd Tanous             {
41704a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
4181abe55efSEd Tanous                 {
41904a258f4SEd Tanous                     if (interfaceName ==
42004a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
4211abe55efSEd Tanous                     {
4221abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
42304a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
4249d3ae10eSAlpana Kumari 
425ac106bf6SEd Tanous                         getMemorySummary(asyncResp, connection.first, path);
4265bc2dc8eSJames Feist 
4275fd0aafbSNinad Palsule                         if constexpr (bmcwebEnableProcMemStatus)
4285fd0aafbSNinad Palsule                         {
4295bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
4301abe55efSEd Tanous                         }
4315fd0aafbSNinad Palsule                     }
43204a258f4SEd Tanous                     else if (interfaceName ==
43304a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
4341abe55efSEd Tanous                     {
4351abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
43604a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
43757e8c9beSAlpana Kumari 
438ac106bf6SEd Tanous                         getProcessorSummary(asyncResp, connection.first, path);
4395bc2dc8eSJames Feist 
4405fd0aafbSNinad Palsule                         if constexpr (bmcwebEnableProcMemStatus)
4415fd0aafbSNinad Palsule                         {
4425bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
4431abe55efSEd Tanous                         }
4445fd0aafbSNinad Palsule                     }
445002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4461abe55efSEd Tanous                     {
4471abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
44804a258f4SEd Tanous                             << "Found UUID, now get its properties.";
449bc1d29deSKrzysztof Grobelny 
450bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
451bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
452bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
453ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec3,
454b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
4551214b7e7SGunnar Mills                                             properties) {
456cb13a392SEd Tanous                             if (ec3)
4571abe55efSEd Tanous                             {
458002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
459002d39b4SEd Tanous                                                  << ec3;
460ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
461c5b2abe0SLewanczyk, Dawid                                 return;
462c5b2abe0SLewanczyk, Dawid                             }
463002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
464c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
46504a258f4SEd Tanous 
466bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
467bc1d29deSKrzysztof Grobelny 
468bc1d29deSKrzysztof Grobelny                             const bool success =
469bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
470bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
471bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
472bc1d29deSKrzysztof Grobelny 
473bc1d29deSKrzysztof Grobelny                             if (!success)
4741abe55efSEd Tanous                             {
475ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
476bc1d29deSKrzysztof Grobelny                                 return;
477bc1d29deSKrzysztof Grobelny                             }
478bc1d29deSKrzysztof Grobelny 
479bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
480bc1d29deSKrzysztof Grobelny                             {
481bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
48204a258f4SEd Tanous                                 if (valueStr.size() == 32)
4831abe55efSEd Tanous                                 {
484029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
485029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
486029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
487029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
48804a258f4SEd Tanous                                 }
489bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
490ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["UUID"] = valueStr;
491c5b2abe0SLewanczyk, Dawid                             }
492bc1d29deSKrzysztof Grobelny                             });
493c5b2abe0SLewanczyk, Dawid                     }
494029573d4SEd Tanous                     else if (interfaceName ==
495029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4961abe55efSEd Tanous                     {
497bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
498bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
499bc1d29deSKrzysztof Grobelny                             path,
500bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
501ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec2,
502b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
5031214b7e7SGunnar Mills                                             propertiesList) {
504cb13a392SEd Tanous                             if (ec2)
505029573d4SEd Tanous                             {
506e4a4b9a9SJames Feist                                 // doesn't have to include this
507e4a4b9a9SJames Feist                                 // interface
508029573d4SEd Tanous                                 return;
509029573d4SEd Tanous                             }
510002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
511029573d4SEd Tanous                                              << " properties for system";
512bc1d29deSKrzysztof Grobelny 
513bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
514bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
515bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
516bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
517bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
518bc1d29deSKrzysztof Grobelny 
519bc1d29deSKrzysztof Grobelny                             const bool success =
520bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
521bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
522bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
523bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
524bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
525bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
526bc1d29deSKrzysztof Grobelny 
527bc1d29deSKrzysztof Grobelny                             if (!success)
528029573d4SEd Tanous                             {
529ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
530bc1d29deSKrzysztof Grobelny                                 return;
531029573d4SEd Tanous                             }
532bc1d29deSKrzysztof Grobelny 
533bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
534bc1d29deSKrzysztof Grobelny                             {
535ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["PartNumber"] =
536bc1d29deSKrzysztof Grobelny                                     *partNumber;
537029573d4SEd Tanous                             }
538bc1d29deSKrzysztof Grobelny 
539bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
540bc1d29deSKrzysztof Grobelny                             {
541ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["SerialNumber"] =
542bc1d29deSKrzysztof Grobelny                                     *serialNumber;
543bc1d29deSKrzysztof Grobelny                             }
544bc1d29deSKrzysztof Grobelny 
545bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
546bc1d29deSKrzysztof Grobelny                             {
547ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["Manufacturer"] =
548bc1d29deSKrzysztof Grobelny                                     *manufacturer;
549bc1d29deSKrzysztof Grobelny                             }
550bc1d29deSKrzysztof Grobelny 
551bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
552bc1d29deSKrzysztof Grobelny                             {
553ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["Model"] = *model;
554bc1d29deSKrzysztof Grobelny                             }
555bc1d29deSKrzysztof Grobelny 
556bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
557bc1d29deSKrzysztof Grobelny                             {
558ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["SubModel"] =
559ac106bf6SEd Tanous                                     *subModel;
560fc5afcf9Sbeccabroek                             }
561c1e236a6SGunnar Mills 
562cb7e1e7bSAndrew Geissler                             // Grab the bios version
563eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
564ac106bf6SEd Tanous                                 asyncResp, sw_util::biosPurpose, "BiosVersion",
565002d39b4SEd Tanous                                 false);
566bc1d29deSKrzysztof Grobelny                             });
567e4a4b9a9SJames Feist 
5681e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5691e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5701e1e598dSJonathan Doman                             path,
5711e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5721e1e598dSJonathan Doman                             "AssetTag",
5731e1e598dSJonathan Doman                             "AssetTag",
574ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec2,
5751e1e598dSJonathan Doman                                         const std::string& value) {
576cb13a392SEd Tanous                             if (ec2)
577e4a4b9a9SJames Feist                             {
578e4a4b9a9SJames Feist                                 // doesn't have to include this
579e4a4b9a9SJames Feist                                 // interface
580e4a4b9a9SJames Feist                                 return;
581e4a4b9a9SJames Feist                             }
582e4a4b9a9SJames Feist 
583ac106bf6SEd Tanous                             asyncResp->res.jsonValue["AssetTag"] = value;
5841e1e598dSJonathan Doman                             });
585029573d4SEd Tanous                     }
586029573d4SEd Tanous                 }
587029573d4SEd Tanous             }
588c5b2abe0SLewanczyk, Dawid         }
5896617338dSEd Tanous         });
590c5b2abe0SLewanczyk, Dawid }
591c5b2abe0SLewanczyk, Dawid 
592c5b2abe0SLewanczyk, Dawid /**
593c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
594c5b2abe0SLewanczyk, Dawid  *
595ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
596c5b2abe0SLewanczyk, Dawid  *
597c5b2abe0SLewanczyk, Dawid  * @return None.
598c5b2abe0SLewanczyk, Dawid  */
599ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
6001abe55efSEd Tanous {
60155c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
6021e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6031e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6041e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6051e1e598dSJonathan Doman         "CurrentHostState",
606ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
6071e1e598dSJonathan Doman                     const std::string& hostState) {
6081abe55efSEd Tanous         if (ec)
6091abe55efSEd Tanous         {
61022228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
61122228c28SAndrew Geissler             {
61222228c28SAndrew Geissler                 // Service not available, no error, just don't return
61322228c28SAndrew Geissler                 // host state info
61422228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
61522228c28SAndrew Geissler                 return;
61622228c28SAndrew Geissler             }
61722228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
618ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
619c5b2abe0SLewanczyk, Dawid             return;
620c5b2abe0SLewanczyk, Dawid         }
6216617338dSEd Tanous 
6221e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
623c5b2abe0SLewanczyk, Dawid         // Verify Host State
6241e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6251abe55efSEd Tanous         {
626ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
627ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
6281abe55efSEd Tanous         }
6291e1e598dSJonathan Doman         else if (hostState ==
6300fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6318c888608SGunnar Mills         {
632ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
633ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
6348c888608SGunnar Mills         }
6351e1e598dSJonathan Doman         else if (hostState ==
6360fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
63783935af9SAndrew Geissler         {
638ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
639ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
64083935af9SAndrew Geissler         }
6410fda0f12SGeorge Liu         else if (
6421e1e598dSJonathan Doman             hostState ==
6430fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6441a2a1437SAndrew Geissler         {
645ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
646ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
6471a2a1437SAndrew Geissler         }
648002d39b4SEd Tanous         else if (hostState ==
6490fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6501a2a1437SAndrew Geissler         {
651ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
652ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
6531a2a1437SAndrew Geissler         }
6541abe55efSEd Tanous         else
6551abe55efSEd Tanous         {
656ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
657ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
658c5b2abe0SLewanczyk, Dawid         }
6591e1e598dSJonathan Doman         });
660c5b2abe0SLewanczyk, Dawid }
661c5b2abe0SLewanczyk, Dawid 
662c5b2abe0SLewanczyk, Dawid /**
663786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
664491d8ee7SSantosh Puranik  *
665491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
666491d8ee7SSantosh Puranik  *
667491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
668491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
669491d8ee7SSantosh Puranik  */
67023a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
671491d8ee7SSantosh Puranik {
672491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
673491d8ee7SSantosh Puranik     {
674491d8ee7SSantosh Puranik         return "None";
675491d8ee7SSantosh Puranik     }
6763174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
677491d8ee7SSantosh Puranik     {
678491d8ee7SSantosh Puranik         return "Hdd";
679491d8ee7SSantosh Puranik     }
6803174e4dfSEd Tanous     if (dbusSource ==
681a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
682491d8ee7SSantosh Puranik     {
683491d8ee7SSantosh Puranik         return "Cd";
684491d8ee7SSantosh Puranik     }
6853174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
686491d8ee7SSantosh Puranik     {
687491d8ee7SSantosh Puranik         return "Pxe";
688491d8ee7SSantosh Puranik     }
6893174e4dfSEd Tanous     if (dbusSource ==
690944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6919f16b2c1SJennifer Lee     {
6929f16b2c1SJennifer Lee         return "Usb";
6939f16b2c1SJennifer Lee     }
694491d8ee7SSantosh Puranik     return "";
695491d8ee7SSantosh Puranik }
696491d8ee7SSantosh Puranik 
697491d8ee7SSantosh Puranik /**
698cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
699cd9a4666SKonstantin Aladyshev  *
700cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
701cd9a4666SKonstantin Aladyshev  *
702cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
703cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
704cd9a4666SKonstantin Aladyshev  */
705cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
706cd9a4666SKonstantin Aladyshev {
707cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
708cd9a4666SKonstantin Aladyshev     {
709cd9a4666SKonstantin Aladyshev         return "Legacy";
710cd9a4666SKonstantin Aladyshev     }
711cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
712cd9a4666SKonstantin Aladyshev     {
713cd9a4666SKonstantin Aladyshev         return "UEFI";
714cd9a4666SKonstantin Aladyshev     }
715cd9a4666SKonstantin Aladyshev     return "";
716cd9a4666SKonstantin Aladyshev }
717cd9a4666SKonstantin Aladyshev 
718cd9a4666SKonstantin Aladyshev /**
719786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
720491d8ee7SSantosh Puranik  *
721491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
722491d8ee7SSantosh Puranik  *
723491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
724491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
725491d8ee7SSantosh Puranik  */
72623a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
727491d8ee7SSantosh Puranik {
728491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
729491d8ee7SSantosh Puranik     {
730491d8ee7SSantosh Puranik         return "None";
731491d8ee7SSantosh Puranik     }
7323174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
733491d8ee7SSantosh Puranik     {
734491d8ee7SSantosh Puranik         return "Diags";
735491d8ee7SSantosh Puranik     }
7363174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
737491d8ee7SSantosh Puranik     {
738491d8ee7SSantosh Puranik         return "BiosSetup";
739491d8ee7SSantosh Puranik     }
740491d8ee7SSantosh Puranik     return "";
741491d8ee7SSantosh Puranik }
742491d8ee7SSantosh Puranik 
743491d8ee7SSantosh Puranik /**
744e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
745e43914b3SAndrew Geissler  *
746e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
747e43914b3SAndrew Geissler  *
748e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
749e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
750e43914b3SAndrew Geissler  */
751e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
752e43914b3SAndrew Geissler {
753e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
754e43914b3SAndrew Geissler     // enum
755e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
756e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
757e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
758e43914b3SAndrew Geissler     {
759e43914b3SAndrew Geissler         rfBpLastState = "None";
760e43914b3SAndrew Geissler     }
761e43914b3SAndrew Geissler     else if (dbusBootProgress ==
762e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
763e43914b3SAndrew Geissler              "PrimaryProcInit")
764e43914b3SAndrew Geissler     {
765e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
766e43914b3SAndrew Geissler     }
767e43914b3SAndrew Geissler     else if (dbusBootProgress ==
768e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
769e43914b3SAndrew Geissler              "BusInit")
770e43914b3SAndrew Geissler     {
771e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
772e43914b3SAndrew Geissler     }
773e43914b3SAndrew Geissler     else if (dbusBootProgress ==
774e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
775e43914b3SAndrew Geissler              "MemoryInit")
776e43914b3SAndrew Geissler     {
777e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
778e43914b3SAndrew Geissler     }
779e43914b3SAndrew Geissler     else if (dbusBootProgress ==
780e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
781e43914b3SAndrew Geissler              "SecondaryProcInit")
782e43914b3SAndrew Geissler     {
783e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
784e43914b3SAndrew Geissler     }
785e43914b3SAndrew Geissler     else if (dbusBootProgress ==
786e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
787e43914b3SAndrew Geissler              "PCIInit")
788e43914b3SAndrew Geissler     {
789e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
790e43914b3SAndrew Geissler     }
791e43914b3SAndrew Geissler     else if (dbusBootProgress ==
792e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
793e43914b3SAndrew Geissler              "SystemSetup")
794e43914b3SAndrew Geissler     {
795e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
796e43914b3SAndrew Geissler     }
797e43914b3SAndrew Geissler     else if (dbusBootProgress ==
798e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
799e43914b3SAndrew Geissler              "SystemInitComplete")
800e43914b3SAndrew Geissler     {
801e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
802e43914b3SAndrew Geissler     }
803e43914b3SAndrew Geissler     else if (dbusBootProgress ==
804e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
805e43914b3SAndrew Geissler              "OSStart")
806e43914b3SAndrew Geissler     {
807e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
808e43914b3SAndrew Geissler     }
809e43914b3SAndrew Geissler     else if (dbusBootProgress ==
810e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
811e43914b3SAndrew Geissler              "OSRunning")
812e43914b3SAndrew Geissler     {
813e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
814e43914b3SAndrew Geissler     }
815e43914b3SAndrew Geissler     else
816e43914b3SAndrew Geissler     {
817e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
818e43914b3SAndrew Geissler                          << dbusBootProgress;
819e43914b3SAndrew Geissler         // Just return the default
820e43914b3SAndrew Geissler     }
821e43914b3SAndrew Geissler     return rfBpLastState;
822e43914b3SAndrew Geissler }
823e43914b3SAndrew Geissler 
824e43914b3SAndrew Geissler /**
825786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
826491d8ee7SSantosh Puranik  *
827491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
828944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
829944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
830491d8ee7SSantosh Puranik  *
831944ffaf9SJohnathan Mantey  * @return Integer error code.
832491d8ee7SSantosh Puranik  */
833ac106bf6SEd Tanous inline int
834ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
835ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
836ac106bf6SEd Tanous                          std::string& bootMode)
837491d8ee7SSantosh Puranik {
838c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
839c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
840944ffaf9SJohnathan Mantey 
841491d8ee7SSantosh Puranik     if (rfSource == "None")
842491d8ee7SSantosh Puranik     {
843944ffaf9SJohnathan Mantey         return 0;
844491d8ee7SSantosh Puranik     }
8453174e4dfSEd Tanous     if (rfSource == "Pxe")
846491d8ee7SSantosh Puranik     {
847944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
848944ffaf9SJohnathan Mantey     }
849944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
850944ffaf9SJohnathan Mantey     {
851944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
852944ffaf9SJohnathan Mantey     }
853944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
854944ffaf9SJohnathan Mantey     {
855944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
856944ffaf9SJohnathan Mantey     }
857944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
858944ffaf9SJohnathan Mantey     {
859944ffaf9SJohnathan Mantey         bootSource =
860944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
861944ffaf9SJohnathan Mantey     }
862944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
863944ffaf9SJohnathan Mantey     {
864944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
865491d8ee7SSantosh Puranik     }
8669f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8679f16b2c1SJennifer Lee     {
868944ffaf9SJohnathan Mantey         bootSource =
869944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8709f16b2c1SJennifer Lee     }
871491d8ee7SSantosh Puranik     else
872491d8ee7SSantosh Puranik     {
8730fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8740fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
875944ffaf9SJohnathan Mantey             << bootSource;
876ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
877944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
878944ffaf9SJohnathan Mantey         return -1;
879491d8ee7SSantosh Puranik     }
880944ffaf9SJohnathan Mantey     return 0;
881491d8ee7SSantosh Puranik }
8821981771bSAli Ahmed 
883978b8803SAndrew Geissler /**
884978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
885978b8803SAndrew Geissler  *
886ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
887978b8803SAndrew Geissler  *
888978b8803SAndrew Geissler  * @return None.
889978b8803SAndrew Geissler  */
890ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
891978b8803SAndrew Geissler {
8921e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8931e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8941e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8951e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
896ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8971e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
898978b8803SAndrew Geissler         if (ec)
899978b8803SAndrew Geissler         {
900978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
901978b8803SAndrew Geissler             // not found
902978b8803SAndrew Geissler             return;
903978b8803SAndrew Geissler         }
904978b8803SAndrew Geissler 
9051e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
906978b8803SAndrew Geissler 
907ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
908e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9091e1e598dSJonathan Doman         });
910978b8803SAndrew Geissler }
911491d8ee7SSantosh Puranik 
912491d8ee7SSantosh Puranik /**
913b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
914b6d5d45cSHieu Huynh  *
915ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
916b6d5d45cSHieu Huynh  *
917b6d5d45cSHieu Huynh  * @return None.
918b6d5d45cSHieu Huynh  */
919b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
920ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
921b6d5d45cSHieu Huynh {
922b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
923b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
924b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
925b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
926ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
927b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
928b6d5d45cSHieu Huynh         if (ec)
929b6d5d45cSHieu Huynh         {
930b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
931b6d5d45cSHieu Huynh             return;
932b6d5d45cSHieu Huynh         }
933b6d5d45cSHieu Huynh 
934b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
935b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
936b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
937b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
938b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
939b6d5d45cSHieu Huynh 
940b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
941ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
942b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
943b6d5d45cSHieu Huynh         });
944b6d5d45cSHieu Huynh }
945b6d5d45cSHieu Huynh 
946b6d5d45cSHieu Huynh /**
947c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
948cd9a4666SKonstantin Aladyshev  *
949ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
950cd9a4666SKonstantin Aladyshev  *
951cd9a4666SKonstantin Aladyshev  * @return None.
952cd9a4666SKonstantin Aladyshev  */
953cd9a4666SKonstantin Aladyshev 
954ac106bf6SEd Tanous inline void
955ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
956cd9a4666SKonstantin Aladyshev {
9571e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9581e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9591e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9601e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
961ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9621e1e598dSJonathan Doman                     const std::string& bootType) {
963cd9a4666SKonstantin Aladyshev         if (ec)
964cd9a4666SKonstantin Aladyshev         {
965cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
966cd9a4666SKonstantin Aladyshev             return;
967cd9a4666SKonstantin Aladyshev         }
968cd9a4666SKonstantin Aladyshev 
9691e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
970cd9a4666SKonstantin Aladyshev 
971ac106bf6SEd Tanous         asyncResp->res
972ac106bf6SEd Tanous             .jsonValue["Boot"]
973002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
974613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
975cd9a4666SKonstantin Aladyshev 
9761e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
977cd9a4666SKonstantin Aladyshev         if (rfType.empty())
978cd9a4666SKonstantin Aladyshev         {
979ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
980cd9a4666SKonstantin Aladyshev             return;
981cd9a4666SKonstantin Aladyshev         }
982cd9a4666SKonstantin Aladyshev 
983ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9841e1e598dSJonathan Doman         });
985cd9a4666SKonstantin Aladyshev }
986cd9a4666SKonstantin Aladyshev 
987cd9a4666SKonstantin Aladyshev /**
988c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
989491d8ee7SSantosh Puranik  *
990ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
991491d8ee7SSantosh Puranik  *
992491d8ee7SSantosh Puranik  * @return None.
993491d8ee7SSantosh Puranik  */
994c21865c4SKonstantin Aladyshev 
995ac106bf6SEd Tanous inline void
996ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
997491d8ee7SSantosh Puranik {
9981e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9991e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10001e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10011e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1002ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10031e1e598dSJonathan Doman                     const std::string& bootModeStr) {
1004491d8ee7SSantosh Puranik         if (ec)
1005491d8ee7SSantosh Puranik         {
1006491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1007ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1008491d8ee7SSantosh Puranik             return;
1009491d8ee7SSantosh Puranik         }
1010491d8ee7SSantosh Puranik 
10111e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
1012491d8ee7SSantosh Puranik 
1013ac106bf6SEd Tanous         asyncResp->res
10140fda0f12SGeorge Liu             .jsonValue["Boot"]
1015002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1016002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1017491d8ee7SSantosh Puranik 
10181e1e598dSJonathan Doman         if (bootModeStr !=
1019491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1020491d8ee7SSantosh Puranik         {
10211e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1022491d8ee7SSantosh Puranik             if (!rfMode.empty())
1023491d8ee7SSantosh Puranik             {
1024ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1025491d8ee7SSantosh Puranik                     rfMode;
1026491d8ee7SSantosh Puranik             }
1027491d8ee7SSantosh Puranik         }
10281e1e598dSJonathan Doman         });
1029491d8ee7SSantosh Puranik }
1030491d8ee7SSantosh Puranik 
1031491d8ee7SSantosh Puranik /**
1032c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1033491d8ee7SSantosh Puranik  *
1034ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1035491d8ee7SSantosh Puranik  *
1036491d8ee7SSantosh Puranik  * @return None.
1037491d8ee7SSantosh Puranik  */
1038c21865c4SKonstantin Aladyshev 
1039c21865c4SKonstantin Aladyshev inline void
1040ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1041491d8ee7SSantosh Puranik {
10421e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10431e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10441e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10451e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1046ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10471e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1048491d8ee7SSantosh Puranik         if (ec)
1049491d8ee7SSantosh Puranik         {
1050491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10515ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10525ef735c8SNan Zhou             {
10535ef735c8SNan Zhou                 return;
10545ef735c8SNan Zhou             }
1055ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1056491d8ee7SSantosh Puranik             return;
1057491d8ee7SSantosh Puranik         }
1058491d8ee7SSantosh Puranik 
10591e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1060491d8ee7SSantosh Puranik 
10611e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1062491d8ee7SSantosh Puranik         if (!rfSource.empty())
1063491d8ee7SSantosh Puranik         {
1064ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1065ac106bf6SEd Tanous                 rfSource;
1066491d8ee7SSantosh Puranik         }
1067cd9a4666SKonstantin Aladyshev 
1068cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1069cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1070ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10711e1e598dSJonathan Doman         });
1072491d8ee7SSantosh Puranik }
1073491d8ee7SSantosh Puranik 
1074491d8ee7SSantosh Puranik /**
1075c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1076c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1077c21865c4SKonstantin Aladyshev  * state
1078491d8ee7SSantosh Puranik  *
1079ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1080491d8ee7SSantosh Puranik  *
1081491d8ee7SSantosh Puranik  * @return None.
1082491d8ee7SSantosh Puranik  */
1083491d8ee7SSantosh Puranik 
1084ac106bf6SEd Tanous inline void processBootOverrideEnable(
1085ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1086c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1087c21865c4SKonstantin Aladyshev {
1088c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1089c21865c4SKonstantin Aladyshev     {
1090ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1091ac106bf6SEd Tanous             "Disabled";
1092c21865c4SKonstantin Aladyshev         return;
1093c21865c4SKonstantin Aladyshev     }
1094c21865c4SKonstantin Aladyshev 
1095c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1096c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10971e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10981e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10991e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
11001e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1101ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1102491d8ee7SSantosh Puranik         if (ec)
1103491d8ee7SSantosh Puranik         {
1104491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1105ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1106491d8ee7SSantosh Puranik             return;
1107491d8ee7SSantosh Puranik         }
1108491d8ee7SSantosh Puranik 
1109c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1110c21865c4SKonstantin Aladyshev         {
1111ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1112ac106bf6SEd Tanous                 "Once";
1113c21865c4SKonstantin Aladyshev         }
1114c21865c4SKonstantin Aladyshev         else
1115c21865c4SKonstantin Aladyshev         {
1116ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1117c21865c4SKonstantin Aladyshev                 "Continuous";
1118c21865c4SKonstantin Aladyshev         }
11191e1e598dSJonathan Doman         });
1120491d8ee7SSantosh Puranik }
1121491d8ee7SSantosh Puranik 
1122491d8ee7SSantosh Puranik /**
1123c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1124c21865c4SKonstantin Aladyshev  *
1125ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1126c21865c4SKonstantin Aladyshev  *
1127c21865c4SKonstantin Aladyshev  * @return None.
1128c21865c4SKonstantin Aladyshev  */
1129c21865c4SKonstantin Aladyshev 
1130c21865c4SKonstantin Aladyshev inline void
1131ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1132c21865c4SKonstantin Aladyshev {
11331e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11341e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11351e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11361e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1137ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
11381e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1139c21865c4SKonstantin Aladyshev         if (ec)
1140c21865c4SKonstantin Aladyshev         {
1141c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
11425ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11435ef735c8SNan Zhou             {
11445ef735c8SNan Zhou                 return;
11455ef735c8SNan Zhou             }
1146ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1147c21865c4SKonstantin Aladyshev             return;
1148c21865c4SKonstantin Aladyshev         }
1149c21865c4SKonstantin Aladyshev 
1150ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11511e1e598dSJonathan Doman         });
1152c21865c4SKonstantin Aladyshev }
1153c21865c4SKonstantin Aladyshev 
1154c21865c4SKonstantin Aladyshev /**
1155c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1156c21865c4SKonstantin Aladyshev  *
1157ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1158c21865c4SKonstantin Aladyshev  *
1159c21865c4SKonstantin Aladyshev  * @return None.
1160c21865c4SKonstantin Aladyshev  */
1161ac106bf6SEd Tanous inline void
1162ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1163c21865c4SKonstantin Aladyshev {
1164c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1165c21865c4SKonstantin Aladyshev 
1166ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1167ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1168ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1169c21865c4SKonstantin Aladyshev }
1170c21865c4SKonstantin Aladyshev 
1171c21865c4SKonstantin Aladyshev /**
1172c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1173c0557e1aSGunnar Mills  *
1174c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1175c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1176c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1177c0557e1aSGunnar Mills  * last power operation time.
1178c0557e1aSGunnar Mills  *
1179ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1180c0557e1aSGunnar Mills  *
1181c0557e1aSGunnar Mills  * @return None.
1182c0557e1aSGunnar Mills  */
1183ac106bf6SEd Tanous inline void
1184ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1185c0557e1aSGunnar Mills {
1186c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1187c0557e1aSGunnar Mills 
11881e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11891e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11901e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11911e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1192ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1193ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1194c0557e1aSGunnar Mills         if (ec)
1195c0557e1aSGunnar Mills         {
1196c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1197c0557e1aSGunnar Mills             return;
1198c0557e1aSGunnar Mills         }
1199c0557e1aSGunnar Mills 
1200c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1201c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
12021e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1203c0557e1aSGunnar Mills 
1204c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1205ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
12062b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
12071e1e598dSJonathan Doman         });
1208c0557e1aSGunnar Mills }
1209c0557e1aSGunnar Mills 
1210c0557e1aSGunnar Mills /**
1211797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1212797d5daeSCorey Hardesty  *
1213797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1214797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1215797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1216797d5daeSCorey Hardesty  * dbus.
1217797d5daeSCorey Hardesty  *
1218ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1219797d5daeSCorey Hardesty  *
1220797d5daeSCorey Hardesty  * @return None.
1221797d5daeSCorey Hardesty  */
1222ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1223ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1224797d5daeSCorey Hardesty {
1225797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1226797d5daeSCorey Hardesty 
1227797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1228797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1229797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1230797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1231ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1232ac106bf6SEd Tanous             const boost::system::error_code& ec,
1233797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1234797d5daeSCorey Hardesty         if (ec)
1235797d5daeSCorey Hardesty         {
1236797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1237797d5daeSCorey Hardesty             {
1238797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1239ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1240797d5daeSCorey Hardesty             }
1241797d5daeSCorey Hardesty             return;
1242797d5daeSCorey Hardesty         }
1243797d5daeSCorey Hardesty 
1244797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1245797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1246797d5daeSCorey Hardesty 
1247797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1248797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1249797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1250797d5daeSCorey Hardesty 
1251797d5daeSCorey Hardesty         if (!success)
1252797d5daeSCorey Hardesty         {
1253ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1254797d5daeSCorey Hardesty             return;
1255797d5daeSCorey Hardesty         }
1256797d5daeSCorey Hardesty 
1257797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1258797d5daeSCorey Hardesty         {
1259ac106bf6SEd Tanous             asyncResp->res
1260ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1261797d5daeSCorey Hardesty                 *attemptsLeft;
1262797d5daeSCorey Hardesty         }
1263797d5daeSCorey Hardesty 
1264797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1265797d5daeSCorey Hardesty         {
1266ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1267797d5daeSCorey Hardesty                 *retryAttempts;
1268797d5daeSCorey Hardesty         }
1269797d5daeSCorey Hardesty         });
1270797d5daeSCorey Hardesty }
1271797d5daeSCorey Hardesty 
1272797d5daeSCorey Hardesty /**
12736bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12746bd5a8d2SGunnar Mills  *
1275ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12766bd5a8d2SGunnar Mills  *
12776bd5a8d2SGunnar Mills  * @return None.
12786bd5a8d2SGunnar Mills  */
1279797d5daeSCorey Hardesty inline void
1280ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12816bd5a8d2SGunnar Mills {
12826bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12836bd5a8d2SGunnar Mills 
12841e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12851e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12861e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12871e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1288ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1289ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12906bd5a8d2SGunnar Mills         if (ec)
12916bd5a8d2SGunnar Mills         {
1292797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1293797d5daeSCorey Hardesty             {
1294797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1295ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1296797d5daeSCorey Hardesty             }
12976bd5a8d2SGunnar Mills             return;
12986bd5a8d2SGunnar Mills         }
12996bd5a8d2SGunnar Mills 
13001e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1301e05aec50SEd Tanous         if (autoRebootEnabled)
13026bd5a8d2SGunnar Mills         {
1303ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13046bd5a8d2SGunnar Mills                 "RetryAttempts";
13056bd5a8d2SGunnar Mills         }
13066bd5a8d2SGunnar Mills         else
13076bd5a8d2SGunnar Mills         {
1308ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1309ac106bf6SEd Tanous                 "Disabled";
13106bd5a8d2SGunnar Mills         }
1311ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
131269f35306SGunnar Mills 
131369f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
131469f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
131569f35306SGunnar Mills         // RetryAttempts.
1316ac106bf6SEd Tanous         asyncResp->res
1317ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1318ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
13191e1e598dSJonathan Doman         });
13206bd5a8d2SGunnar Mills }
13216bd5a8d2SGunnar Mills 
13226bd5a8d2SGunnar Mills /**
1323797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1324797d5daeSCorey Hardesty  *
1325ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1326797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1327797d5daeSCorey Hardesty  *
1328797d5daeSCorey Hardesty  *@return None.
1329797d5daeSCorey Hardesty  */
1330797d5daeSCorey Hardesty 
1331ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1332ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1333797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1334797d5daeSCorey Hardesty {
1335797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
13369ae226faSGeorge Liu     sdbusplus::asio::setProperty(
13379ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
13389ae226faSGeorge Liu         "/xyz/openbmc_project/state/host0",
13399ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
13409ae226faSGeorge Liu         retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1341797d5daeSCorey Hardesty             if (ec)
1342797d5daeSCorey Hardesty             {
1343797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR
13449ae226faSGeorge Liu                     << "DBUS response error: Set setAutomaticRetryAttempts"
13459ae226faSGeorge Liu                     << ec;
1346ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1347797d5daeSCorey Hardesty                 return;
1348797d5daeSCorey Hardesty             }
13499ae226faSGeorge Liu         });
1350797d5daeSCorey Hardesty }
1351797d5daeSCorey Hardesty 
13528d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13538d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13548d69c668SEd Tanous {
13558d69c668SEd Tanous     if (value ==
13568d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13578d69c668SEd Tanous     {
13588d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13598d69c668SEd Tanous     }
13608d69c668SEd Tanous     if (value ==
13618d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13628d69c668SEd Tanous     {
13638d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13648d69c668SEd Tanous     }
13658d69c668SEd Tanous     if (value ==
13668d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore")
13678d69c668SEd Tanous     {
13688d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13698d69c668SEd Tanous     }
13708d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13718d69c668SEd Tanous     {
13728d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13738d69c668SEd Tanous     }
13748d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13758d69c668SEd Tanous }
1376797d5daeSCorey Hardesty /**
1377c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1378c6a620f2SGeorge Liu  *
1379ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1380c6a620f2SGeorge Liu  *
1381c6a620f2SGeorge Liu  * @return None.
1382c6a620f2SGeorge Liu  */
13838d1b46d7Szhanghch05 inline void
1384ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1385c6a620f2SGeorge Liu {
1386c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1387c6a620f2SGeorge Liu 
13881e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13891e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13901e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13911e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1392ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13935e7e2dc5SEd Tanous                     const std::string& policy) {
1394c6a620f2SGeorge Liu         if (ec)
1395c6a620f2SGeorge Liu         {
1396c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1397c6a620f2SGeorge Liu             return;
1398c6a620f2SGeorge Liu         }
13998d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
14008d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
14018d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1402c6a620f2SGeorge Liu         {
1403ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1404c6a620f2SGeorge Liu             return;
1405c6a620f2SGeorge Liu         }
1406c6a620f2SGeorge Liu 
14078d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
14081e1e598dSJonathan Doman         });
1409c6a620f2SGeorge Liu }
1410c6a620f2SGeorge Liu 
1411c6a620f2SGeorge Liu /**
14129dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
14139dcfe8c1SAlbert Zhang  *
14149dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
14159dcfe8c1SAlbert Zhang  *
14169dcfe8c1SAlbert Zhang  * @return None.
14179dcfe8c1SAlbert Zhang  */
14189dcfe8c1SAlbert Zhang inline void
14199dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14209dcfe8c1SAlbert Zhang {
14219dcfe8c1SAlbert Zhang     BMCWEB_LOG_DEBUG << "Get Stop Boot On Fault";
14229dcfe8c1SAlbert Zhang 
14239dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
14249dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
14259dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
14269dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
14279dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
14289dcfe8c1SAlbert Zhang         if (ec)
14299dcfe8c1SAlbert Zhang         {
14309dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
14319dcfe8c1SAlbert Zhang             {
14329dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
14339dcfe8c1SAlbert Zhang             }
14349dcfe8c1SAlbert Zhang             return;
14359dcfe8c1SAlbert Zhang         }
14369dcfe8c1SAlbert Zhang 
14379dcfe8c1SAlbert Zhang         if (value)
14389dcfe8c1SAlbert Zhang         {
14399dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
14409dcfe8c1SAlbert Zhang         }
14419dcfe8c1SAlbert Zhang         else
14429dcfe8c1SAlbert Zhang         {
14439dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
14449dcfe8c1SAlbert Zhang         }
14459dcfe8c1SAlbert Zhang         });
14469dcfe8c1SAlbert Zhang }
14479dcfe8c1SAlbert Zhang 
14489dcfe8c1SAlbert Zhang /**
14491981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14501981771bSAli Ahmed  * TPM is required for booting the host.
14511981771bSAli Ahmed  *
1452ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14531981771bSAli Ahmed  *
14541981771bSAli Ahmed  * @return None.
14551981771bSAli Ahmed  */
14561981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1457ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14581981771bSAli Ahmed {
14591981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1460e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1461e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1462e99073f5SGeorge Liu     dbus::utility::getSubTree(
1463e99073f5SGeorge Liu         "/", 0, interfaces,
1464ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1465b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14661981771bSAli Ahmed         if (ec)
14671981771bSAli Ahmed         {
1468002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1469002d39b4SEd Tanous                              << ec;
14701981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14711981771bSAli Ahmed             // error occurs
14721981771bSAli Ahmed             return;
14731981771bSAli Ahmed         }
147426f6976fSEd Tanous         if (subtree.empty())
14751981771bSAli Ahmed         {
14761981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14771981771bSAli Ahmed             // if there is no instance found
14781981771bSAli Ahmed             return;
14791981771bSAli Ahmed         }
14801981771bSAli Ahmed 
14811981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14821981771bSAli Ahmed         if (subtree.size() > 1)
14831981771bSAli Ahmed         {
14841981771bSAli Ahmed             BMCWEB_LOG_DEBUG
14851981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
14861981771bSAli Ahmed                 << subtree.size();
14871981771bSAli Ahmed             // Throw an internal Error and return
1488ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14891981771bSAli Ahmed             return;
14901981771bSAli Ahmed         }
14911981771bSAli Ahmed 
14921981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14931981771bSAli Ahmed         // field
14941981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14951981771bSAli Ahmed         {
14961981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1497ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14981981771bSAli Ahmed             return;
14991981771bSAli Ahmed         }
15001981771bSAli Ahmed 
15011981771bSAli Ahmed         const std::string& path = subtree[0].first;
15021981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15031981771bSAli Ahmed 
15041981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
15051e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
15061e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
15071e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1508ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1509ac106bf6SEd Tanous                         bool tpmRequired) {
15108a592810SEd Tanous             if (ec2)
15111981771bSAli Ahmed             {
1512002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
15138a592810SEd Tanous                                  << ec2;
1514ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15151981771bSAli Ahmed                 return;
15161981771bSAli Ahmed             }
15171981771bSAli Ahmed 
15181e1e598dSJonathan Doman             if (tpmRequired)
15191981771bSAli Ahmed             {
1520ac106bf6SEd Tanous                 asyncResp->res
1521ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15221981771bSAli Ahmed                     "Required";
15231981771bSAli Ahmed             }
15241981771bSAli Ahmed             else
15251981771bSAli Ahmed             {
1526ac106bf6SEd Tanous                 asyncResp->res
1527ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15281981771bSAli Ahmed                     "Disabled";
15291981771bSAli Ahmed             }
15301e1e598dSJonathan Doman             });
1531e99073f5SGeorge Liu         });
15321981771bSAli Ahmed }
15331981771bSAli Ahmed 
15341981771bSAli Ahmed /**
15351c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
15361c05dae3SAli Ahmed  * TPM is required for booting the host.
15371c05dae3SAli Ahmed  *
1538ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
15391c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
15401c05dae3SAli Ahmed  *
15411c05dae3SAli Ahmed  * @return None.
15421c05dae3SAli Ahmed  */
15431c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1544ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
15451c05dae3SAli Ahmed {
15461c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1547e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1548e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1549e99073f5SGeorge Liu     dbus::utility::getSubTree(
1550e99073f5SGeorge Liu         "/", 0, interfaces,
1551ac106bf6SEd Tanous         [asyncResp,
1552e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1553e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15541c05dae3SAli Ahmed         if (ec)
15551c05dae3SAli Ahmed         {
1556002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1557002d39b4SEd Tanous                              << ec;
1558ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15591c05dae3SAli Ahmed             return;
15601c05dae3SAli Ahmed         }
156126f6976fSEd Tanous         if (subtree.empty())
15621c05dae3SAli Ahmed         {
1563ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15641c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15651c05dae3SAli Ahmed             return;
15661c05dae3SAli Ahmed         }
15671c05dae3SAli Ahmed 
15681c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15691c05dae3SAli Ahmed         if (subtree.size() > 1)
15701c05dae3SAli Ahmed         {
15711c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
15721c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
15731c05dae3SAli Ahmed                 << subtree.size();
15741c05dae3SAli Ahmed             // Throw an internal Error and return
1575ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15761c05dae3SAli Ahmed             return;
15771c05dae3SAli Ahmed         }
15781c05dae3SAli Ahmed 
15791c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15801c05dae3SAli Ahmed         // field
15811c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15821c05dae3SAli Ahmed         {
15831c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1584ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15851c05dae3SAli Ahmed             return;
15861c05dae3SAli Ahmed         }
15871c05dae3SAli Ahmed 
15881c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15891c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15901c05dae3SAli Ahmed 
15911c05dae3SAli Ahmed         if (serv.empty())
15921c05dae3SAli Ahmed         {
15931c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1594ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15951c05dae3SAli Ahmed             return;
15961c05dae3SAli Ahmed         }
15971c05dae3SAli Ahmed 
15981c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
15999ae226faSGeorge Liu         sdbusplus::asio::setProperty(
16009ae226faSGeorge Liu             *crow::connections::systemBus, serv, path,
16019ae226faSGeorge Liu             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
1602ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
16038a592810SEd Tanous             if (ec2)
16041c05dae3SAli Ahmed             {
16050fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
16060fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
16078a592810SEd Tanous                     << ec2;
1608ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16091c05dae3SAli Ahmed                 return;
16101c05dae3SAli Ahmed             }
16111c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
16129ae226faSGeorge Liu             });
1613e99073f5SGeorge Liu         });
16141c05dae3SAli Ahmed }
16151c05dae3SAli Ahmed 
16161c05dae3SAli Ahmed /**
1617491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1618491d8ee7SSantosh Puranik  *
1619ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1620cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1621cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1622cd9a4666SKonstantin Aladyshev  */
1623ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1624cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1625cd9a4666SKonstantin Aladyshev {
1626c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1627cd9a4666SKonstantin Aladyshev 
1628c21865c4SKonstantin Aladyshev     if (!bootType)
1629cd9a4666SKonstantin Aladyshev     {
1630c21865c4SKonstantin Aladyshev         return;
1631c21865c4SKonstantin Aladyshev     }
1632c21865c4SKonstantin Aladyshev 
1633cd9a4666SKonstantin Aladyshev     // Source target specified
1634cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1635cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1636cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1637cd9a4666SKonstantin Aladyshev     {
1638cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1639cd9a4666SKonstantin Aladyshev     }
1640cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1641cd9a4666SKonstantin Aladyshev     {
1642cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1643cd9a4666SKonstantin Aladyshev     }
1644cd9a4666SKonstantin Aladyshev     else
1645cd9a4666SKonstantin Aladyshev     {
1646cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1647cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1648cd9a4666SKonstantin Aladyshev                          << *bootType;
1649ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1650cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1651cd9a4666SKonstantin Aladyshev         return;
1652cd9a4666SKonstantin Aladyshev     }
1653cd9a4666SKonstantin Aladyshev 
1654cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1655cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1656cd9a4666SKonstantin Aladyshev 
16579ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16589ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16599ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
16609ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
1661ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1662cd9a4666SKonstantin Aladyshev         if (ec)
1663cd9a4666SKonstantin Aladyshev         {
1664cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1665cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1666cd9a4666SKonstantin Aladyshev             {
1667ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1668cd9a4666SKonstantin Aladyshev                 return;
1669cd9a4666SKonstantin Aladyshev             }
1670ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1671cd9a4666SKonstantin Aladyshev             return;
1672cd9a4666SKonstantin Aladyshev         }
1673cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
16749ae226faSGeorge Liu         });
1675cd9a4666SKonstantin Aladyshev }
1676cd9a4666SKonstantin Aladyshev 
1677cd9a4666SKonstantin Aladyshev /**
1678cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1679cd9a4666SKonstantin Aladyshev  *
1680ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1681ac106bf6SEd Tanous  * message.
1682c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1683c21865c4SKonstantin Aladyshev  * @return Integer error code.
1684c21865c4SKonstantin Aladyshev  */
1685ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1686c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1687c21865c4SKonstantin Aladyshev {
1688c21865c4SKonstantin Aladyshev     if (!bootEnable)
1689c21865c4SKonstantin Aladyshev     {
1690c21865c4SKonstantin Aladyshev         return;
1691c21865c4SKonstantin Aladyshev     }
1692c21865c4SKonstantin Aladyshev     // Source target specified
1693c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1694c21865c4SKonstantin Aladyshev 
1695c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1696c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1697c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1698c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1699c21865c4SKonstantin Aladyshev     {
1700c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1701c21865c4SKonstantin Aladyshev     }
1702c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1703c21865c4SKonstantin Aladyshev     {
1704c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1705c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1706c21865c4SKonstantin Aladyshev     }
1707c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1708c21865c4SKonstantin Aladyshev     {
1709c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1710c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1711c21865c4SKonstantin Aladyshev     }
1712c21865c4SKonstantin Aladyshev     else
1713c21865c4SKonstantin Aladyshev     {
17140fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
17150fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1716c21865c4SKonstantin Aladyshev             << *bootEnable;
1717ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1718c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1719c21865c4SKonstantin Aladyshev         return;
1720c21865c4SKonstantin Aladyshev     }
1721c21865c4SKonstantin Aladyshev 
1722c21865c4SKonstantin Aladyshev     // Act on validated parameters
1723c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1724c21865c4SKonstantin Aladyshev 
17259ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17269ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17279ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17289ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
1729ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
17308a592810SEd Tanous         if (ec2)
1731c21865c4SKonstantin Aladyshev         {
17328a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1733ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1734c21865c4SKonstantin Aladyshev             return;
1735c21865c4SKonstantin Aladyshev         }
1736c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
17379ae226faSGeorge Liu         });
1738c21865c4SKonstantin Aladyshev 
1739c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1740c21865c4SKonstantin Aladyshev     {
1741c21865c4SKonstantin Aladyshev         return;
1742c21865c4SKonstantin Aladyshev     }
1743c21865c4SKonstantin Aladyshev 
1744c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1745c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1746c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1747c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1748c21865c4SKonstantin Aladyshev 
17499ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17509ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17519ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot/one_time",
17529ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
1753ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1754c21865c4SKonstantin Aladyshev         if (ec)
1755c21865c4SKonstantin Aladyshev         {
1756c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1757ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1758c21865c4SKonstantin Aladyshev             return;
1759c21865c4SKonstantin Aladyshev         }
1760c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
17619ae226faSGeorge Liu         });
1762c21865c4SKonstantin Aladyshev }
1763c21865c4SKonstantin Aladyshev 
1764c21865c4SKonstantin Aladyshev /**
1765c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1766c21865c4SKonstantin Aladyshev  *
1767ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1768491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1769491d8ee7SSantosh Puranik  *
1770265c1602SJohnathan Mantey  * @return Integer error code.
1771491d8ee7SSantosh Puranik  */
1772ac106bf6SEd Tanous inline void
1773ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1774cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1775491d8ee7SSantosh Puranik {
1776c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1777c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1778944ffaf9SJohnathan Mantey 
1779c21865c4SKonstantin Aladyshev     if (!bootSource)
1780491d8ee7SSantosh Puranik     {
1781c21865c4SKonstantin Aladyshev         return;
1782c21865c4SKonstantin Aladyshev     }
1783c21865c4SKonstantin Aladyshev 
1784491d8ee7SSantosh Puranik     // Source target specified
1785491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1786491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1787ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1788ac106bf6SEd Tanous                              bootModeStr) != 0)
1789491d8ee7SSantosh Puranik     {
1790944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1791944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1792491d8ee7SSantosh Puranik             << *bootSource;
1793ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1794491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1795491d8ee7SSantosh Puranik         return;
1796491d8ee7SSantosh Puranik     }
1797491d8ee7SSantosh Puranik 
1798944ffaf9SJohnathan Mantey     // Act on validated parameters
1799944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1800944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1801944ffaf9SJohnathan Mantey 
18029ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18039ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18049ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18059ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
1806ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1807491d8ee7SSantosh Puranik         if (ec)
1808491d8ee7SSantosh Puranik         {
1809491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1810ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1811491d8ee7SSantosh Puranik             return;
1812491d8ee7SSantosh Puranik         }
1813491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
18149ae226faSGeorge Liu         });
1815944ffaf9SJohnathan Mantey 
18169ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18179ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18189ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18199ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
1820ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1821491d8ee7SSantosh Puranik         if (ec)
1822491d8ee7SSantosh Puranik         {
1823491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1824ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1825491d8ee7SSantosh Puranik             return;
1826491d8ee7SSantosh Puranik         }
1827491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
18289ae226faSGeorge Liu         });
1829cd9a4666SKonstantin Aladyshev }
1830944ffaf9SJohnathan Mantey 
1831cd9a4666SKonstantin Aladyshev /**
1832c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1833491d8ee7SSantosh Puranik  *
1834ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1835491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1836cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1837491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1838491d8ee7SSantosh Puranik  *
1839265c1602SJohnathan Mantey  * @return Integer error code.
1840491d8ee7SSantosh Puranik  */
1841c21865c4SKonstantin Aladyshev 
1842ac106bf6SEd Tanous inline void
1843ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1844c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1845c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1846c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1847491d8ee7SSantosh Puranik {
1848491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1849491d8ee7SSantosh Puranik 
1850ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1851ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1852ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1853491d8ee7SSantosh Puranik }
1854491d8ee7SSantosh Puranik 
1855c6a620f2SGeorge Liu /**
185698e386ecSGunnar Mills  * @brief Sets AssetTag
185798e386ecSGunnar Mills  *
1858ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
185998e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
186098e386ecSGunnar Mills  *
186198e386ecSGunnar Mills  * @return None.
186298e386ecSGunnar Mills  */
1863ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
186498e386ecSGunnar Mills                         const std::string& assetTag)
186598e386ecSGunnar Mills {
1866e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1867e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1868e99073f5SGeorge Liu     dbus::utility::getSubTree(
1869e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1870ac106bf6SEd Tanous         [asyncResp,
1871e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1872b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
187398e386ecSGunnar Mills         if (ec)
187498e386ecSGunnar Mills         {
187598e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1876ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
187798e386ecSGunnar Mills             return;
187898e386ecSGunnar Mills         }
187926f6976fSEd Tanous         if (subtree.empty())
188098e386ecSGunnar Mills         {
188198e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1882ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188398e386ecSGunnar Mills             return;
188498e386ecSGunnar Mills         }
188598e386ecSGunnar Mills         // Assume only 1 system D-Bus object
188698e386ecSGunnar Mills         // Throw an error if there is more than 1
188798e386ecSGunnar Mills         if (subtree.size() > 1)
188898e386ecSGunnar Mills         {
188998e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1890ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189198e386ecSGunnar Mills             return;
189298e386ecSGunnar Mills         }
189398e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
189498e386ecSGunnar Mills         {
189598e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1896ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189798e386ecSGunnar Mills             return;
189898e386ecSGunnar Mills         }
189998e386ecSGunnar Mills 
190098e386ecSGunnar Mills         const std::string& path = subtree[0].first;
190198e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
190298e386ecSGunnar Mills 
190398e386ecSGunnar Mills         if (service.empty())
190498e386ecSGunnar Mills         {
190598e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1906ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
190798e386ecSGunnar Mills             return;
190898e386ecSGunnar Mills         }
190998e386ecSGunnar Mills 
19109ae226faSGeorge Liu         sdbusplus::asio::setProperty(
19119ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
19129ae226faSGeorge Liu             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
19139ae226faSGeorge Liu             assetTag, [asyncResp](const boost::system::error_code& ec2) {
191498e386ecSGunnar Mills                 if (ec2)
191598e386ecSGunnar Mills                 {
1916002d39b4SEd Tanous                     BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1917002d39b4SEd Tanous                                      << ec2;
1918ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
191998e386ecSGunnar Mills                     return;
192098e386ecSGunnar Mills                 }
19219ae226faSGeorge Liu             });
1922e99073f5SGeorge Liu         });
192398e386ecSGunnar Mills }
192498e386ecSGunnar Mills 
192598e386ecSGunnar Mills /**
19269dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
19279dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
19289dcfe8c1SAlbert Zhang  *
19299dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
19309dcfe8c1SAlbert Zhang  * stopBootOnFault
19319dcfe8c1SAlbert Zhang  *
19329dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
19339dcfe8c1SAlbert Zhang  */
19349dcfe8c1SAlbert Zhang inline std::optional<bool>
19359dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
19369dcfe8c1SAlbert Zhang {
19379dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
19389dcfe8c1SAlbert Zhang     {
19399dcfe8c1SAlbert Zhang         return true;
19409dcfe8c1SAlbert Zhang     }
19419dcfe8c1SAlbert Zhang 
19429dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
19439dcfe8c1SAlbert Zhang     {
19449dcfe8c1SAlbert Zhang         return false;
19459dcfe8c1SAlbert Zhang     }
19469dcfe8c1SAlbert Zhang 
19479dcfe8c1SAlbert Zhang     return std::nullopt;
19489dcfe8c1SAlbert Zhang }
19499dcfe8c1SAlbert Zhang 
19509dcfe8c1SAlbert Zhang /**
19519dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
19529dcfe8c1SAlbert Zhang  *
19539dcfe8c1SAlbert Zhang  * @param[in] aResp   Shared pointer for generating response message.
19549dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
19559dcfe8c1SAlbert Zhang  *
19569dcfe8c1SAlbert Zhang  * @return None.
19579dcfe8c1SAlbert Zhang  */
19589dcfe8c1SAlbert Zhang inline void setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19599dcfe8c1SAlbert Zhang                                const std::string& stopBootOnFault)
19609dcfe8c1SAlbert Zhang {
19619dcfe8c1SAlbert Zhang     BMCWEB_LOG_DEBUG << "Set Stop Boot On Fault.";
19629dcfe8c1SAlbert Zhang 
19639dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
19649dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
19659dcfe8c1SAlbert Zhang     {
19669dcfe8c1SAlbert Zhang         BMCWEB_LOG_DEBUG << "Invalid property value for StopBootOnFault: "
19679dcfe8c1SAlbert Zhang                          << stopBootOnFault;
19689dcfe8c1SAlbert Zhang         messages::propertyValueNotInList(aResp->res, stopBootOnFault,
19699dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
19709dcfe8c1SAlbert Zhang         return;
19719dcfe8c1SAlbert Zhang     }
19729dcfe8c1SAlbert Zhang 
19739dcfe8c1SAlbert Zhang     sdbusplus::asio::setProperty(*crow::connections::systemBus,
19749dcfe8c1SAlbert Zhang                                  "xyz.openbmc_project.Settings",
19759dcfe8c1SAlbert Zhang                                  "/xyz/openbmc_project/logging/settings",
19769dcfe8c1SAlbert Zhang                                  "xyz.openbmc_project.Logging.Settings",
19779dcfe8c1SAlbert Zhang                                  "QuiesceOnHwError", *stopBootEnabled,
19789dcfe8c1SAlbert Zhang                                  [aResp](const boost::system::error_code& ec) {
19799dcfe8c1SAlbert Zhang         if (ec)
19809dcfe8c1SAlbert Zhang         {
19819dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
19829dcfe8c1SAlbert Zhang             {
19839dcfe8c1SAlbert Zhang                 messages::internalError(aResp->res);
19849dcfe8c1SAlbert Zhang             }
19859dcfe8c1SAlbert Zhang             return;
19869dcfe8c1SAlbert Zhang         }
19879dcfe8c1SAlbert Zhang     });
19889dcfe8c1SAlbert Zhang }
19899dcfe8c1SAlbert Zhang 
19909dcfe8c1SAlbert Zhang /**
199169f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
199269f35306SGunnar Mills  *
1993ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
199469f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
199569f35306SGunnar Mills  *
199669f35306SGunnar Mills  * @return None.
199769f35306SGunnar Mills  */
1998ac106bf6SEd Tanous inline void
1999ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2000f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
200169f35306SGunnar Mills {
200269f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
200369f35306SGunnar Mills 
200469f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
2005543f4400SEd Tanous     bool autoRebootEnabled = false;
200669f35306SGunnar Mills 
200769f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
200869f35306SGunnar Mills     {
200969f35306SGunnar Mills         autoRebootEnabled = false;
201069f35306SGunnar Mills     }
201169f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
201269f35306SGunnar Mills     {
201369f35306SGunnar Mills         autoRebootEnabled = true;
201469f35306SGunnar Mills     }
201569f35306SGunnar Mills     else
201669f35306SGunnar Mills     {
20170fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
201869f35306SGunnar Mills                          << automaticRetryConfig;
2019ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
202069f35306SGunnar Mills                                          "AutomaticRetryConfig");
202169f35306SGunnar Mills         return;
202269f35306SGunnar Mills     }
202369f35306SGunnar Mills 
20249ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20259ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20269ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/auto_reboot",
20279ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
20289ae226faSGeorge Liu         autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
202969f35306SGunnar Mills             if (ec)
203069f35306SGunnar Mills             {
2031ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
203269f35306SGunnar Mills                 return;
203369f35306SGunnar Mills             }
20349ae226faSGeorge Liu         });
203569f35306SGunnar Mills }
203669f35306SGunnar Mills 
20378d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
20388d69c668SEd Tanous {
20398d69c668SEd Tanous     if (policy == "AlwaysOn")
20408d69c668SEd Tanous     {
20418d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
20428d69c668SEd Tanous     }
20438d69c668SEd Tanous     if (policy == "AlwaysOff")
20448d69c668SEd Tanous     {
20458d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
20468d69c668SEd Tanous     }
20478d69c668SEd Tanous     if (policy == "LastState")
20488d69c668SEd Tanous     {
20498d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
20508d69c668SEd Tanous     }
20518d69c668SEd Tanous     return "";
20528d69c668SEd Tanous }
20538d69c668SEd Tanous 
205469f35306SGunnar Mills /**
2055c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
2056c6a620f2SGeorge Liu  *
2057ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2058c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
2059c6a620f2SGeorge Liu  *
2060c6a620f2SGeorge Liu  * @return None.
2061c6a620f2SGeorge Liu  */
20628d1b46d7Szhanghch05 inline void
2063ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20648d69c668SEd Tanous                           std::string_view policy)
2065c6a620f2SGeorge Liu {
2066c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
2067c6a620f2SGeorge Liu 
20688d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2069c6a620f2SGeorge Liu 
20708d69c668SEd Tanous     if (powerRestorePolicy.empty())
2071c6a620f2SGeorge Liu     {
2072ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20734e69c904SGunnar Mills                                          "PowerRestorePolicy");
2074c6a620f2SGeorge Liu         return;
2075c6a620f2SGeorge Liu     }
2076c6a620f2SGeorge Liu 
20779ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20789ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20799ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
20809ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
20819ae226faSGeorge Liu         powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2082c6a620f2SGeorge Liu             if (ec)
2083c6a620f2SGeorge Liu             {
2084ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2085c6a620f2SGeorge Liu                 return;
2086c6a620f2SGeorge Liu             }
20879ae226faSGeorge Liu         });
2088c6a620f2SGeorge Liu }
2089c6a620f2SGeorge Liu 
2090a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2091a6349918SAppaRao Puli /**
2092a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2093a6349918SAppaRao Puli  *
2094ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
2095a6349918SAppaRao Puli  *
2096a6349918SAppaRao Puli  * @return None.
2097a6349918SAppaRao Puli  */
2098ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
2099a6349918SAppaRao Puli {
2100a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
2101bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2102bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2103bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
2104ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2105b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2106b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2107ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2108ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
210950626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
211050626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
211150626f4fSJames Feist 
2112a6349918SAppaRao Puli         if (ec)
2113a6349918SAppaRao Puli         {
2114a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2115b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2116b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2117a6349918SAppaRao Puli             return;
2118a6349918SAppaRao Puli         }
2119a6349918SAppaRao Puli 
2120a6349918SAppaRao Puli         const bool* provState = nullptr;
2121a6349918SAppaRao Puli         const bool* lockState = nullptr;
2122bc1d29deSKrzysztof Grobelny 
2123bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
21240d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
21250d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2126bc1d29deSKrzysztof Grobelny 
2127bc1d29deSKrzysztof Grobelny         if (!success)
2128a6349918SAppaRao Puli         {
2129ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2130bc1d29deSKrzysztof Grobelny             return;
2131a6349918SAppaRao Puli         }
2132a6349918SAppaRao Puli 
2133a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2134a6349918SAppaRao Puli         {
2135a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
2136ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2137a6349918SAppaRao Puli             return;
2138a6349918SAppaRao Puli         }
2139a6349918SAppaRao Puli 
2140a6349918SAppaRao Puli         if (*provState == true)
2141a6349918SAppaRao Puli         {
2142a6349918SAppaRao Puli             if (*lockState == true)
2143a6349918SAppaRao Puli             {
2144a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2145a6349918SAppaRao Puli             }
2146a6349918SAppaRao Puli             else
2147a6349918SAppaRao Puli             {
2148a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2149a6349918SAppaRao Puli             }
2150a6349918SAppaRao Puli         }
2151a6349918SAppaRao Puli         else
2152a6349918SAppaRao Puli         {
2153a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2154a6349918SAppaRao Puli         }
2155bc1d29deSKrzysztof Grobelny         });
2156a6349918SAppaRao Puli }
2157a6349918SAppaRao Puli #endif
2158a6349918SAppaRao Puli 
2159491d8ee7SSantosh Puranik /**
21603a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
21613a2d0424SChris Cain  *
2162ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21633a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
21643a2d0424SChris Cain  *
21653a2d0424SChris Cain  * @return None.
21663a2d0424SChris Cain  */
2167ac106bf6SEd Tanous inline void
2168ac106bf6SEd Tanous     translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21693a2d0424SChris Cain                        const std::string& modeValue)
21703a2d0424SChris Cain {
21710fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21723a2d0424SChris Cain     {
2173ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "Static";
21743a2d0424SChris Cain     }
21750fda0f12SGeorge Liu     else if (
21760fda0f12SGeorge Liu         modeValue ==
21770fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21783a2d0424SChris Cain     {
2179ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
21803a2d0424SChris Cain     }
21810fda0f12SGeorge Liu     else if (modeValue ==
21820fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21833a2d0424SChris Cain     {
2184ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
21853a2d0424SChris Cain     }
21860fda0f12SGeorge Liu     else if (modeValue ==
21870fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
21883a2d0424SChris Cain     {
2189ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "OEM";
21903a2d0424SChris Cain     }
21913a2d0424SChris Cain     else
21923a2d0424SChris Cain     {
21933a2d0424SChris Cain         // Any other values would be invalid
21943a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
2195ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
21963a2d0424SChris Cain     }
21973a2d0424SChris Cain }
21983a2d0424SChris Cain 
21993a2d0424SChris Cain /**
22003a2d0424SChris Cain  * @brief Retrieves system power mode
22013a2d0424SChris Cain  *
2202ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22033a2d0424SChris Cain  *
22043a2d0424SChris Cain  * @return None.
22053a2d0424SChris Cain  */
2206ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22073a2d0424SChris Cain {
22083a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
22093a2d0424SChris Cain 
22103a2d0424SChris Cain     // Get Power Mode object path:
2211e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2212e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2213e99073f5SGeorge Liu     dbus::utility::getSubTree(
2214e99073f5SGeorge Liu         "/", 0, interfaces,
2215ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2216b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22173a2d0424SChris Cain         if (ec)
22183a2d0424SChris Cain         {
2219002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2220002d39b4SEd Tanous                              << ec;
22213a2d0424SChris Cain             // This is an optional D-Bus object so just return if
22223a2d0424SChris Cain             // error occurs
22233a2d0424SChris Cain             return;
22243a2d0424SChris Cain         }
22253a2d0424SChris Cain         if (subtree.empty())
22263a2d0424SChris Cain         {
22273a2d0424SChris Cain             // As noted above, this is an optional interface so just return
22283a2d0424SChris Cain             // if there is no instance found
22293a2d0424SChris Cain             return;
22303a2d0424SChris Cain         }
22313a2d0424SChris Cain         if (subtree.size() > 1)
22323a2d0424SChris Cain         {
22333a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22343a2d0424SChris Cain             // error
22353a2d0424SChris Cain             BMCWEB_LOG_DEBUG
22363a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
22373a2d0424SChris Cain                 << subtree.size();
2238ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22393a2d0424SChris Cain             return;
22403a2d0424SChris Cain         }
22413a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22423a2d0424SChris Cain         {
22433a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2244ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22453a2d0424SChris Cain             return;
22463a2d0424SChris Cain         }
22473a2d0424SChris Cain         const std::string& path = subtree[0].first;
22483a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22493a2d0424SChris Cain         if (service.empty())
22503a2d0424SChris Cain         {
22513a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2252ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22533a2d0424SChris Cain             return;
22543a2d0424SChris Cain         }
22553a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
22561e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
22571e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
22581e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2259ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
22601e1e598dSJonathan Doman                         const std::string& pmode) {
22618a592810SEd Tanous             if (ec2)
22623a2d0424SChris Cain             {
2263002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
22648a592810SEd Tanous                                  << ec2;
2265ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22663a2d0424SChris Cain                 return;
22673a2d0424SChris Cain             }
22683a2d0424SChris Cain 
2269ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2270002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
22713a2d0424SChris Cain 
22721e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
2273ac106bf6SEd Tanous             translatePowerMode(asyncResp, pmode);
22741e1e598dSJonathan Doman             });
2275e99073f5SGeorge Liu         });
22763a2d0424SChris Cain }
22773a2d0424SChris Cain 
22783a2d0424SChris Cain /**
22793a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22803a2d0424SChris Cain  * name associated with that string
22813a2d0424SChris Cain  *
2282ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22833a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
22843a2d0424SChris Cain  *
22853a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22863a2d0424SChris Cain  */
22873a2d0424SChris Cain inline std::string
2288ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22893a2d0424SChris Cain                       const std::string& modeString)
22903a2d0424SChris Cain {
22913a2d0424SChris Cain     std::string mode;
22923a2d0424SChris Cain 
22933a2d0424SChris Cain     if (modeString == "Static")
22943a2d0424SChris Cain     {
22953a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22963a2d0424SChris Cain     }
22973a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
22983a2d0424SChris Cain     {
22990fda0f12SGeorge Liu         mode =
23000fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
23013a2d0424SChris Cain     }
23023a2d0424SChris Cain     else if (modeString == "PowerSaving")
23033a2d0424SChris Cain     {
23043a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
23053a2d0424SChris Cain     }
23063a2d0424SChris Cain     else
23073a2d0424SChris Cain     {
2308ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, modeString,
2309ac106bf6SEd Tanous                                          "PowerMode");
23103a2d0424SChris Cain     }
23113a2d0424SChris Cain     return mode;
23123a2d0424SChris Cain }
23133a2d0424SChris Cain 
23143a2d0424SChris Cain /**
23153a2d0424SChris Cain  * @brief Sets system power mode.
23163a2d0424SChris Cain  *
2317ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
23183a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
23193a2d0424SChris Cain  *
23203a2d0424SChris Cain  * @return None.
23213a2d0424SChris Cain  */
2322ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23233a2d0424SChris Cain                          const std::string& pmode)
23243a2d0424SChris Cain {
23253a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
23263a2d0424SChris Cain 
2327ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
23283a2d0424SChris Cain     if (powerMode.empty())
23293a2d0424SChris Cain     {
23303a2d0424SChris Cain         return;
23313a2d0424SChris Cain     }
23323a2d0424SChris Cain 
23333a2d0424SChris Cain     // Get Power Mode object path:
2334e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2335e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2336e99073f5SGeorge Liu     dbus::utility::getSubTree(
2337e99073f5SGeorge Liu         "/", 0, interfaces,
2338ac106bf6SEd Tanous         [asyncResp,
2339e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2340b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23413a2d0424SChris Cain         if (ec)
23423a2d0424SChris Cain         {
2343002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2344002d39b4SEd Tanous                              << ec;
23453a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2346ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23473a2d0424SChris Cain             return;
23483a2d0424SChris Cain         }
23493a2d0424SChris Cain         if (subtree.empty())
23503a2d0424SChris Cain         {
23513a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2352ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23533a2d0424SChris Cain                                        "PowerMode");
23543a2d0424SChris Cain             return;
23553a2d0424SChris Cain         }
23563a2d0424SChris Cain         if (subtree.size() > 1)
23573a2d0424SChris Cain         {
23583a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
23593a2d0424SChris Cain             // error
23603a2d0424SChris Cain             BMCWEB_LOG_DEBUG
23613a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
23623a2d0424SChris Cain                 << subtree.size();
2363ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23643a2d0424SChris Cain             return;
23653a2d0424SChris Cain         }
23663a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23673a2d0424SChris Cain         {
23683a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2369ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23703a2d0424SChris Cain             return;
23713a2d0424SChris Cain         }
23723a2d0424SChris Cain         const std::string& path = subtree[0].first;
23733a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
23743a2d0424SChris Cain         if (service.empty())
23753a2d0424SChris Cain         {
23763a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2377ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23783a2d0424SChris Cain             return;
23793a2d0424SChris Cain         }
23803a2d0424SChris Cain 
23813a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
23823a2d0424SChris Cain                          << path;
23833a2d0424SChris Cain 
23843a2d0424SChris Cain         // Set the Power Mode property
23859ae226faSGeorge Liu         sdbusplus::asio::setProperty(
23869ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
23879ae226faSGeorge Liu             "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
2388ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
23898a592810SEd Tanous             if (ec2)
23903a2d0424SChris Cain             {
2391ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23923a2d0424SChris Cain                 return;
23933a2d0424SChris Cain             }
23949ae226faSGeorge Liu             });
2395e99073f5SGeorge Liu         });
23963a2d0424SChris Cain }
23973a2d0424SChris Cain 
23983a2d0424SChris Cain /**
239951709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
240051709ffdSYong Li  *
240151709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
240251709ffdSYong Li  *
240351709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
240451709ffdSYong Li  * translation cannot be done, returns an empty string.
240551709ffdSYong Li  */
240623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
240751709ffdSYong Li {
240851709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
240951709ffdSYong Li     {
241051709ffdSYong Li         return "None";
241151709ffdSYong Li     }
24123174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
241351709ffdSYong Li     {
241451709ffdSYong Li         return "ResetSystem";
241551709ffdSYong Li     }
24163174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
241751709ffdSYong Li     {
241851709ffdSYong Li         return "PowerDown";
241951709ffdSYong Li     }
24203174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
242151709ffdSYong Li     {
242251709ffdSYong Li         return "PowerCycle";
242351709ffdSYong Li     }
242451709ffdSYong Li 
242551709ffdSYong Li     return "";
242651709ffdSYong Li }
242751709ffdSYong Li 
242851709ffdSYong Li /**
2429c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2430c45f0082SYong Li  *
2431c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2432c45f0082SYong Li  *
2433c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2434c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2435c45f0082SYong Li  */
2436c45f0082SYong Li 
243723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2438c45f0082SYong Li {
2439c45f0082SYong Li     if (rfAction == "None")
2440c45f0082SYong Li     {
2441c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2442c45f0082SYong Li     }
24433174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2444c45f0082SYong Li     {
2445c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2446c45f0082SYong Li     }
24473174e4dfSEd Tanous     if (rfAction == "PowerDown")
2448c45f0082SYong Li     {
2449c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2450c45f0082SYong Li     }
24513174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2452c45f0082SYong Li     {
2453c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2454c45f0082SYong Li     }
2455c45f0082SYong Li 
2456c45f0082SYong Li     return "";
2457c45f0082SYong Li }
2458c45f0082SYong Li 
2459c45f0082SYong Li /**
246051709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
246151709ffdSYong Li  *
2462ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
246351709ffdSYong Li  *
246451709ffdSYong Li  * @return None.
246551709ffdSYong Li  */
24668d1b46d7Szhanghch05 inline void
2467ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
246851709ffdSYong Li {
246951709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2470bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2471bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2472bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2473bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2474ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2475b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
247651709ffdSYong Li         if (ec)
247751709ffdSYong Li         {
247851709ffdSYong Li             // watchdog service is stopped
247951709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
248051709ffdSYong Li             return;
248151709ffdSYong Li         }
248251709ffdSYong Li 
248351709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
248451709ffdSYong Li 
248551709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2486ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
248751709ffdSYong Li 
248851709ffdSYong Li         // watchdog service is running/enabled
248951709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
249051709ffdSYong Li 
2491bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2492bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
249351709ffdSYong Li 
2494bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2495bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2496bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2497bc1d29deSKrzysztof Grobelny 
2498bc1d29deSKrzysztof Grobelny         if (!success)
249951709ffdSYong Li         {
2500ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2501601af5edSChicago Duan             return;
250251709ffdSYong Li         }
250351709ffdSYong Li 
2504bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
250551709ffdSYong Li         {
2506bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
250751709ffdSYong Li         }
250851709ffdSYong Li 
2509bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2510bc1d29deSKrzysztof Grobelny         {
2511bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
251251709ffdSYong Li             if (action.empty())
251351709ffdSYong Li             {
2514ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2515601af5edSChicago Duan                 return;
251651709ffdSYong Li             }
251751709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
251851709ffdSYong Li         }
2519bc1d29deSKrzysztof Grobelny         });
252051709ffdSYong Li }
252151709ffdSYong Li 
252251709ffdSYong Li /**
2523c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2524c45f0082SYong Li  *
2525ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2526c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2527c45f0082SYong Li  *                       RF request.
2528c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2529c45f0082SYong Li  *
2530c45f0082SYong Li  * @return None.
2531c45f0082SYong Li  */
2532ac106bf6SEd Tanous inline void
2533ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2534c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2535c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2536c45f0082SYong Li {
2537c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2538c45f0082SYong Li 
2539c45f0082SYong Li     if (wdtTimeOutAction)
2540c45f0082SYong Li     {
2541c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2542c45f0082SYong Li         // check if TimeOut Action is Valid
2543c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2544c45f0082SYong Li         {
2545c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2546c45f0082SYong Li                              << *wdtTimeOutAction;
2547ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2548c45f0082SYong Li                                              "TimeoutAction");
2549c45f0082SYong Li             return;
2550c45f0082SYong Li         }
2551c45f0082SYong Li 
25529ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25539ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25549ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25559ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
25569ae226faSGeorge Liu             wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2557c45f0082SYong Li                 if (ec)
2558c45f0082SYong Li                 {
2559c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2560ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2561c45f0082SYong Li                     return;
2562c45f0082SYong Li                 }
25639ae226faSGeorge Liu             });
2564c45f0082SYong Li     }
2565c45f0082SYong Li 
2566c45f0082SYong Li     if (wdtEnable)
2567c45f0082SYong Li     {
25689ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25699ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25709ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25719ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
2572ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2573c45f0082SYong Li             if (ec)
2574c45f0082SYong Li             {
2575c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2576ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2577c45f0082SYong Li                 return;
2578c45f0082SYong Li             }
25799ae226faSGeorge Liu             });
2580c45f0082SYong Li     }
2581c45f0082SYong Li }
2582c45f0082SYong Li 
258337bbf98cSChris Cain /**
258437bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
258537bbf98cSChris Cain  *
2586ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
258737bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
258837bbf98cSChris Cain  *
258937bbf98cSChris Cain  * @return true if successful
259037bbf98cSChris Cain  */
25911e5b7c88SJiaqing Zhao inline bool
2592ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25931e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
259437bbf98cSChris Cain {
2595bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2596bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2597bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2598bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2599bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2600bc1d29deSKrzysztof Grobelny 
2601bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2602bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26032661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26042661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26052661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2606bc1d29deSKrzysztof Grobelny 
2607bc1d29deSKrzysztof Grobelny     if (!success)
260837bbf98cSChris Cain     {
260937bbf98cSChris Cain         return false;
261037bbf98cSChris Cain     }
2611bc1d29deSKrzysztof Grobelny 
2612bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
261337bbf98cSChris Cain     {
2614ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
261537bbf98cSChris Cain     }
2616bc1d29deSKrzysztof Grobelny 
2617bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
261837bbf98cSChris Cain     {
2619ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2620bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
262137bbf98cSChris Cain     }
2622bc1d29deSKrzysztof Grobelny 
2623bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2624bc1d29deSKrzysztof Grobelny     {
2625bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2626ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
262737bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
262837bbf98cSChris Cain                 .count();
262937bbf98cSChris Cain     }
2630bc1d29deSKrzysztof Grobelny 
2631bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
263237bbf98cSChris Cain     {
2633ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2634bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
263537bbf98cSChris Cain     }
2636bc1d29deSKrzysztof Grobelny 
2637bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
263837bbf98cSChris Cain     {
2639bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2640ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
264137bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
264237bbf98cSChris Cain                 .count();
264337bbf98cSChris Cain     }
264437bbf98cSChris Cain 
264537bbf98cSChris Cain     return true;
264637bbf98cSChris Cain }
264737bbf98cSChris Cain 
264837bbf98cSChris Cain /**
264937bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
265037bbf98cSChris Cain  *
2651ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
265237bbf98cSChris Cain  *
265337bbf98cSChris Cain  * @return None.
265437bbf98cSChris Cain  */
2655ac106bf6SEd Tanous inline void
2656ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
265737bbf98cSChris Cain {
265837bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
265937bbf98cSChris Cain 
266037bbf98cSChris Cain     // Get IdlePowerSaver object path:
2661e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2662e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2663e99073f5SGeorge Liu     dbus::utility::getSubTree(
2664e99073f5SGeorge Liu         "/", 0, interfaces,
2665ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2666b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
266737bbf98cSChris Cain         if (ec)
266837bbf98cSChris Cain         {
266937bbf98cSChris Cain             BMCWEB_LOG_DEBUG
267037bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
267137bbf98cSChris Cain                 << ec;
2672ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
267337bbf98cSChris Cain             return;
267437bbf98cSChris Cain         }
267537bbf98cSChris Cain         if (subtree.empty())
267637bbf98cSChris Cain         {
267737bbf98cSChris Cain             // This is an optional interface so just return
267837bbf98cSChris Cain             // if there is no instance found
267937bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
268037bbf98cSChris Cain             return;
268137bbf98cSChris Cain         }
268237bbf98cSChris Cain         if (subtree.size() > 1)
268337bbf98cSChris Cain         {
268437bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
268537bbf98cSChris Cain             // is an error
268637bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
268737bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
268837bbf98cSChris Cain                              << subtree.size();
2689ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269037bbf98cSChris Cain             return;
269137bbf98cSChris Cain         }
269237bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
269337bbf98cSChris Cain         {
269437bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2695ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269637bbf98cSChris Cain             return;
269737bbf98cSChris Cain         }
269837bbf98cSChris Cain         const std::string& path = subtree[0].first;
269937bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
270037bbf98cSChris Cain         if (service.empty())
270137bbf98cSChris Cain         {
2702002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2703ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
270437bbf98cSChris Cain             return;
270537bbf98cSChris Cain         }
270637bbf98cSChris Cain 
270737bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2708bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2709bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2710bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2711ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27121e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
27138a592810SEd Tanous             if (ec2)
271437bbf98cSChris Cain             {
271537bbf98cSChris Cain                 BMCWEB_LOG_ERROR
27168a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
2717ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271837bbf98cSChris Cain                 return;
271937bbf98cSChris Cain             }
272037bbf98cSChris Cain 
2721ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
272237bbf98cSChris Cain             {
2723ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272437bbf98cSChris Cain                 return;
272537bbf98cSChris Cain             }
2726bc1d29deSKrzysztof Grobelny             });
2727e99073f5SGeorge Liu         });
272837bbf98cSChris Cain 
272937bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
273037bbf98cSChris Cain }
273137bbf98cSChris Cain 
273237bbf98cSChris Cain /**
273337bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
273437bbf98cSChris Cain  *
2735ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
273637bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
273737bbf98cSChris Cain  *                       RF request.
273837bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
273937bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
274037bbf98cSChris Cain  * before entering idle state.
274137bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
274237bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
274337bbf98cSChris Cain  * before exiting idle state
274437bbf98cSChris Cain  *
274537bbf98cSChris Cain  * @return None.
274637bbf98cSChris Cain  */
2747ac106bf6SEd Tanous inline void
2748ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
274937bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
275037bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
275137bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
275237bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
275337bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
275437bbf98cSChris Cain {
275537bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
275637bbf98cSChris Cain 
275737bbf98cSChris Cain     // Get IdlePowerSaver object path:
2758e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2759e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2760e99073f5SGeorge Liu     dbus::utility::getSubTree(
2761e99073f5SGeorge Liu         "/", 0, interfaces,
2762ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2763e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2764b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
276537bbf98cSChris Cain         if (ec)
276637bbf98cSChris Cain         {
276737bbf98cSChris Cain             BMCWEB_LOG_DEBUG
276837bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
276937bbf98cSChris Cain                 << ec;
2770ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
277137bbf98cSChris Cain             return;
277237bbf98cSChris Cain         }
277337bbf98cSChris Cain         if (subtree.empty())
277437bbf98cSChris Cain         {
277537bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2776ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
277737bbf98cSChris Cain                                        "IdlePowerSaver");
277837bbf98cSChris Cain             return;
277937bbf98cSChris Cain         }
278037bbf98cSChris Cain         if (subtree.size() > 1)
278137bbf98cSChris Cain         {
278237bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
278337bbf98cSChris Cain             // is an error
27840fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
27850fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
278637bbf98cSChris Cain                 << subtree.size();
2787ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
278837bbf98cSChris Cain             return;
278937bbf98cSChris Cain         }
279037bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
279137bbf98cSChris Cain         {
279237bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2793ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
279437bbf98cSChris Cain             return;
279537bbf98cSChris Cain         }
279637bbf98cSChris Cain         const std::string& path = subtree[0].first;
279737bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
279837bbf98cSChris Cain         if (service.empty())
279937bbf98cSChris Cain         {
2800002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2801ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
280237bbf98cSChris Cain             return;
280337bbf98cSChris Cain         }
280437bbf98cSChris Cain 
280537bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
280637bbf98cSChris Cain         // need to be updated
280737bbf98cSChris Cain 
280837bbf98cSChris Cain         if (ipsEnable)
280937bbf98cSChris Cain         {
28109ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28119ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28129ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
28139ae226faSGeorge Liu                 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
28148a592810SEd Tanous                     if (ec2)
281537bbf98cSChris Cain                     {
28168a592810SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2817ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
281837bbf98cSChris Cain                         return;
281937bbf98cSChris Cain                     }
28209ae226faSGeorge Liu                 });
282137bbf98cSChris Cain         }
282237bbf98cSChris Cain         if (ipsEnterUtil)
282337bbf98cSChris Cain         {
28249ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28259ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28269ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28279ae226faSGeorge Liu                 "EnterUtilizationPercent", *ipsEnterUtil,
2828ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28298a592810SEd Tanous                 if (ec2)
283037bbf98cSChris Cain                 {
28318a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2832ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
283337bbf98cSChris Cain                     return;
283437bbf98cSChris Cain                 }
28359ae226faSGeorge Liu                 });
283637bbf98cSChris Cain         }
283737bbf98cSChris Cain         if (ipsEnterTime)
283837bbf98cSChris Cain         {
283937bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
284037bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
28419ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28429ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28439ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28449ae226faSGeorge Liu                 "EnterDwellTime", timeMilliseconds,
2845ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28468a592810SEd Tanous                 if (ec2)
284737bbf98cSChris Cain                 {
28488a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2849ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
285037bbf98cSChris Cain                     return;
285137bbf98cSChris Cain                 }
28529ae226faSGeorge Liu                 });
285337bbf98cSChris Cain         }
285437bbf98cSChris Cain         if (ipsExitUtil)
285537bbf98cSChris Cain         {
28569ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28579ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28589ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28599ae226faSGeorge Liu                 "ExitUtilizationPercent", *ipsExitUtil,
2860ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28618a592810SEd Tanous                 if (ec2)
286237bbf98cSChris Cain                 {
28638a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2864ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
286537bbf98cSChris Cain                     return;
286637bbf98cSChris Cain                 }
28679ae226faSGeorge Liu                 });
286837bbf98cSChris Cain         }
286937bbf98cSChris Cain         if (ipsExitTime)
287037bbf98cSChris Cain         {
287137bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
287237bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
28739ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28749ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28759ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28769ae226faSGeorge Liu                 "ExitDwellTime", timeMilliseconds,
2877ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28788a592810SEd Tanous                 if (ec2)
287937bbf98cSChris Cain                 {
28808a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2881ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
288237bbf98cSChris Cain                     return;
288337bbf98cSChris Cain                 }
28849ae226faSGeorge Liu                 });
288537bbf98cSChris Cain         }
2886e99073f5SGeorge Liu         });
288737bbf98cSChris Cain 
288837bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
288937bbf98cSChris Cain }
289037bbf98cSChris Cain 
2891c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2892dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2893dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2894dd60b9edSEd Tanous {
2895dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2896dd60b9edSEd Tanous     {
2897dd60b9edSEd Tanous         return;
2898dd60b9edSEd Tanous     }
2899dd60b9edSEd Tanous     asyncResp->res.addHeader(
2900dd60b9edSEd Tanous         boost::beast::http::field::link,
2901dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2902dd60b9edSEd Tanous }
2903dd60b9edSEd Tanous 
2904c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2905c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2906c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29071abe55efSEd Tanous {
29083ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2909f4c99e70SEd Tanous     {
2910f4c99e70SEd Tanous         return;
2911f4c99e70SEd Tanous     }
2912dd60b9edSEd Tanous 
2913dd60b9edSEd Tanous     asyncResp->res.addHeader(
2914dd60b9edSEd Tanous         boost::beast::http::field::link,
2915dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
29168d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
29170f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
29188d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
29198d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2920462023adSSunitha Harish 
29217f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
29227f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
29237f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
29247f3e84a1SEd Tanous     {
29257f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
29267f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29277f3e84a1SEd Tanous         return;
29287f3e84a1SEd Tanous     }
29297f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
29307f3e84a1SEd Tanous     nlohmann::json::object_t system;
29317f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
29327f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
29331e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2934002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
29351e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2936002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
29375e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
29381e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
29397f3e84a1SEd Tanous         if (ec2)
2940462023adSSunitha Harish         {
29417f3e84a1SEd Tanous             return;
29427f3e84a1SEd Tanous         }
29437f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
29447f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
29457f3e84a1SEd Tanous         {
29467f3e84a1SEd Tanous             BMCWEB_LOG_CRITICAL << "Count wasn't found??";
29477f3e84a1SEd Tanous             return;
29487f3e84a1SEd Tanous         }
29497f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
29507f3e84a1SEd Tanous         if (count == nullptr)
29517f3e84a1SEd Tanous         {
29527f3e84a1SEd Tanous             BMCWEB_LOG_CRITICAL << "Count wasn't found??";
29537f3e84a1SEd Tanous             return;
29547f3e84a1SEd Tanous         }
29557f3e84a1SEd Tanous         *count = *count + 1;
2956462023adSSunitha Harish         BMCWEB_LOG_DEBUG << "Hypervisor is available";
29577f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
29581476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2959002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
29607f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
29611e1e598dSJonathan Doman         });
2962c1e219d5SEd Tanous }
2963c1e219d5SEd Tanous 
2964c1e219d5SEd Tanous /**
29657e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
29667e860f15SJohn Edward Broadbent  */
29674f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29687e860f15SJohn Edward Broadbent {
296989492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
297089492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
297189492a15SPatrick Williams     constexpr const char* interfaceName =
29727e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
297389492a15SPatrick Williams     constexpr const char* method = "NMI";
29747e860f15SJohn Edward Broadbent 
29757e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
29765e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
29777e860f15SJohn Edward Broadbent         if (ec)
29787e860f15SJohn Edward Broadbent         {
29797e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
29807e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
29817e860f15SJohn Edward Broadbent             return;
29827e860f15SJohn Edward Broadbent         }
29837e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
29847e860f15SJohn Edward Broadbent         },
29857e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
29867e860f15SJohn Edward Broadbent }
2987c5b2abe0SLewanczyk, Dawid 
2988c5b2abe0SLewanczyk, Dawid /**
2989fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
2990fc903b3dSAndrew Geissler  */
2991fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
2992fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
2993fc903b3dSAndrew Geissler                                          std::string_view resetType,
2994fc903b3dSAndrew Geissler                                          crow::Response& res)
2995fc903b3dSAndrew Geissler {
2996fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
2997fc903b3dSAndrew Geissler     {
2998fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
2999fc903b3dSAndrew Geissler         return;
3000fc903b3dSAndrew Geissler     }
3001fc903b3dSAndrew Geissler 
3002fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
3003fc903b3dSAndrew Geissler     {
3004fc903b3dSAndrew Geissler         BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
3005fc903b3dSAndrew Geissler         messages::internalError(res);
3006fc903b3dSAndrew Geissler         return;
3007fc903b3dSAndrew Geissler     }
3008fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
3009fc903b3dSAndrew Geissler 
3010fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
3011fc903b3dSAndrew Geissler     // user to retry in a bit
3012fc903b3dSAndrew Geissler     if ((errorMessage ==
3013fc903b3dSAndrew Geissler          std::string_view(
3014fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3015fc903b3dSAndrew Geissler         (errorMessage ==
3016fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3017fc903b3dSAndrew Geissler     {
3018fc903b3dSAndrew Geissler         BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
3019fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
3020fc903b3dSAndrew Geissler         return;
3021fc903b3dSAndrew Geissler     }
3022fc903b3dSAndrew Geissler 
3023fc903b3dSAndrew Geissler     BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
3024fc903b3dSAndrew Geissler                      << " sdbusplus:" << errorMessage;
3025fc903b3dSAndrew Geissler     messages::internalError(res);
3026fc903b3dSAndrew Geissler }
3027fc903b3dSAndrew Geissler 
3028c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
3029c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
30307f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3031c1e219d5SEd Tanous     const std::string& systemName)
3032c1e219d5SEd Tanous {
30333ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
303445ca1b86SEd Tanous     {
303545ca1b86SEd Tanous         return;
303645ca1b86SEd Tanous     }
3037c1e219d5SEd Tanous     if (systemName != "system")
3038c1e219d5SEd Tanous     {
3039c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3040c1e219d5SEd Tanous                                    systemName);
3041c1e219d5SEd Tanous         return;
3042c1e219d5SEd Tanous     }
30437f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
30447f3e84a1SEd Tanous     {
30457f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30467f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3047c1e219d5SEd Tanous                                    systemName);
30487f3e84a1SEd Tanous         return;
30497f3e84a1SEd Tanous     }
30509712f8acSEd Tanous     std::string resetType;
3051c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3052cc340dd9SEd Tanous     {
3053cc340dd9SEd Tanous         return;
3054cc340dd9SEd Tanous     }
3055cc340dd9SEd Tanous 
3056d22c8396SJason M. Bills     // Get the command and host vs. chassis
3057cc340dd9SEd Tanous     std::string command;
3058543f4400SEd Tanous     bool hostCommand = true;
3059d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
3060cc340dd9SEd Tanous     {
3061cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
3062d22c8396SJason M. Bills         hostCommand = true;
3063d22c8396SJason M. Bills     }
3064d22c8396SJason M. Bills     else if (resetType == "ForceOff")
3065d22c8396SJason M. Bills     {
3066d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3067d22c8396SJason M. Bills         hostCommand = false;
3068d22c8396SJason M. Bills     }
3069d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
3070d22c8396SJason M. Bills     {
3071c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
307286a0851aSJason M. Bills         hostCommand = true;
3073cc340dd9SEd Tanous     }
30749712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
3075cc340dd9SEd Tanous     {
3076cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
3077d22c8396SJason M. Bills         hostCommand = true;
3078cc340dd9SEd Tanous     }
30799712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3080cc340dd9SEd Tanous     {
30810fda0f12SGeorge Liu         command =
30820fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3083d22c8396SJason M. Bills         hostCommand = true;
3084d22c8396SJason M. Bills     }
3085d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3086d22c8396SJason M. Bills     {
308786a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
308886a0851aSJason M. Bills         hostCommand = true;
3089cc340dd9SEd Tanous     }
3090bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3091bfd5b826SLakshminarayana R. Kammath     {
3092bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3093bfd5b826SLakshminarayana R. Kammath         return;
3094bfd5b826SLakshminarayana R. Kammath     }
3095cc340dd9SEd Tanous     else
3096cc340dd9SEd Tanous     {
3097c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3098cc340dd9SEd Tanous         return;
3099cc340dd9SEd Tanous     }
3100cc340dd9SEd Tanous 
3101d22c8396SJason M. Bills     if (hostCommand)
3102d22c8396SJason M. Bills     {
31039ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31049ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
31059ae226faSGeorge Liu             "/xyz/openbmc_project/state/host0",
31069ae226faSGeorge Liu             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
31079ae226faSGeorge Liu             command,
3108fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3109fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3110cc340dd9SEd Tanous             if (ec)
3111cc340dd9SEd Tanous             {
3112fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3113fc903b3dSAndrew Geissler                                              asyncResp->res);
3114fc903b3dSAndrew Geissler 
3115cc340dd9SEd Tanous                 return;
3116cc340dd9SEd Tanous             }
3117f12894f8SJason M. Bills             messages::success(asyncResp->res);
31189ae226faSGeorge Liu             });
3119cc340dd9SEd Tanous     }
3120d22c8396SJason M. Bills     else
3121d22c8396SJason M. Bills     {
31229ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31239ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
31249ae226faSGeorge Liu             "/xyz/openbmc_project/state/chassis0",
31259ae226faSGeorge Liu             "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
31269ae226faSGeorge Liu             command,
3127fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3128fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3129d22c8396SJason M. Bills             if (ec)
3130d22c8396SJason M. Bills             {
3131fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3132fc903b3dSAndrew Geissler                                              asyncResp->res);
3133d22c8396SJason M. Bills                 return;
3134d22c8396SJason M. Bills             }
3135d22c8396SJason M. Bills             messages::success(asyncResp->res);
31369ae226faSGeorge Liu             });
3137d22c8396SJason M. Bills     }
3138d22c8396SJason M. Bills }
3139cc340dd9SEd Tanous 
3140c1e219d5SEd Tanous inline void handleComputerSystemHead(
3141dd60b9edSEd Tanous     App& app, const crow::Request& req,
31427f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31437f3e84a1SEd Tanous     const std::string& /*systemName*/)
3144dd60b9edSEd Tanous {
3145dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3146dd60b9edSEd Tanous     {
3147dd60b9edSEd Tanous         return;
3148dd60b9edSEd Tanous     }
3149dd60b9edSEd Tanous 
3150dd60b9edSEd Tanous     asyncResp->res.addHeader(
3151dd60b9edSEd Tanous         boost::beast::http::field::link,
3152dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3153dd60b9edSEd Tanous }
3154dd60b9edSEd Tanous 
31555c3e9272SAbhishek Patel inline void afterPortRequest(
31565c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31575c3e9272SAbhishek Patel     const boost::system::error_code& ec,
31585c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
31595c3e9272SAbhishek Patel {
31605c3e9272SAbhishek Patel     if (ec)
31615c3e9272SAbhishek Patel     {
31625c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
31635c3e9272SAbhishek Patel         return;
31645c3e9272SAbhishek Patel     }
31655c3e9272SAbhishek Patel     for (const auto& data : socketData)
31665c3e9272SAbhishek Patel     {
31675c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
31685c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
31695c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
31705c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
31715c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
31725c3e9272SAbhishek Patel         // need to retrieve port number for
31735c3e9272SAbhishek Patel         // obmc-console-ssh service
31745c3e9272SAbhishek Patel         if (protocolName == "SSH")
31755c3e9272SAbhishek Patel         {
31765c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
317781c4e330SEd Tanous                                           const boost::system::error_code& ec1,
31785c3e9272SAbhishek Patel                                           int portNumber) {
31795c3e9272SAbhishek Patel                 if (ec1)
31805c3e9272SAbhishek Patel                 {
31815c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
31825c3e9272SAbhishek Patel                     return;
31835c3e9272SAbhishek Patel                 }
31845c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
31855c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
31865c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
31875c3e9272SAbhishek Patel             });
31885c3e9272SAbhishek Patel         }
31895c3e9272SAbhishek Patel     }
31905c3e9272SAbhishek Patel }
3191c1e219d5SEd Tanous 
3192c1e219d5SEd Tanous inline void
3193c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
319422d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3195c1e219d5SEd Tanous                             const std::string& systemName)
3196c1e219d5SEd Tanous {
31973ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
319845ca1b86SEd Tanous     {
319945ca1b86SEd Tanous         return;
320045ca1b86SEd Tanous     }
3201746b56f3SAsmitha Karunanithi 
32027f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32037f3e84a1SEd Tanous     {
32047f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32057f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32067f3e84a1SEd Tanous                                    systemName);
32077f3e84a1SEd Tanous         return;
32087f3e84a1SEd Tanous     }
32097f3e84a1SEd Tanous 
3210746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3211746b56f3SAsmitha Karunanithi     {
3212746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3213746b56f3SAsmitha Karunanithi         return;
3214746b56f3SAsmitha Karunanithi     }
3215746b56f3SAsmitha Karunanithi 
321622d268cbSEd Tanous     if (systemName != "system")
321722d268cbSEd Tanous     {
321822d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
321922d268cbSEd Tanous                                    systemName);
322022d268cbSEd Tanous         return;
322122d268cbSEd Tanous     }
3222dd60b9edSEd Tanous     asyncResp->res.addHeader(
3223dd60b9edSEd Tanous         boost::beast::http::field::link,
3224dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
32258d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
322637bbf98cSChris Cain         "#ComputerSystem.v1_16_0.ComputerSystem";
32278d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
32288d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
32298d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
32308d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
32318d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
32325fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
32335fd0aafbSNinad Palsule     {
32348d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
32358d1b46d7Szhanghch05             "Disabled";
32368d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
32378d1b46d7Szhanghch05             "Disabled";
32385fd0aafbSNinad Palsule     }
3239cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3240*dfb2b408SPriyanga Ramasamy         double(0);
3241002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
324204a258f4SEd Tanous 
32431476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
32441476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
32451476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
32461476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
32471476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
32481476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
32493179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
32503179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3251029573d4SEd Tanous 
3252002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
32531476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3254c1e219d5SEd Tanous     asyncResp->res
3255c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
32561476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3257c5b2abe0SLewanczyk, Dawid 
32581476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
32591476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
32601476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
32611476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3262c4bf6374SJason M. Bills 
32631476687dSEd Tanous     nlohmann::json::array_t managedBy;
32641476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
32651476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3266002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
32671476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
32681476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
32690e8ac5e7SGunnar Mills 
32700e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3271002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3272c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
32731476687dSEd Tanous 
3274c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
32751476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3276c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
32771476687dSEd Tanous         "Press ~. to exit console";
32785c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
32795c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
32800e8ac5e7SGunnar Mills 
32810e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
32820e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3283002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3284c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3285613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3286613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
32871476687dSEd Tanous 
32880e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
328913451e39SWilly Tu 
329013451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
329113451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
329213451e39SWilly Tu     {
32937a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3294b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
32952ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3296e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3297e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3298b49ac873SJames Feist 
32997a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
33007a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
33017a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3302914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3303b49ac873SJames Feist             if (ec)
3304b49ac873SJames Feist             {
3305b49ac873SJames Feist                 // no inventory
3306b49ac873SJames Feist                 return;
3307b49ac873SJames Feist             }
3308b49ac873SJames Feist 
3309914e2d5dSEd Tanous             health->inventory = resp;
33107a1dbc48SGeorge Liu             });
3311b49ac873SJames Feist         health->populate();
331213451e39SWilly Tu     }
3313b49ac873SJames Feist 
3314002d39b4SEd Tanous     getMainChassisId(asyncResp,
3315002d39b4SEd Tanous                      [](const std::string& chassisId,
33168d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3317b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3318b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3319ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3320ef4c65b7SEd Tanous                                                    chassisId);
3321002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3322c5d03ff4SJennifer Lee     });
3323a3002228SAppaRao Puli 
33249f8bfa7cSGunnar Mills     getLocationIndicatorActive(asyncResp);
33259f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3326a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
33275bc2dc8eSJames Feist     getComputerSystem(asyncResp, health);
33286c34de48SEd Tanous     getHostState(asyncResp);
3329491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3330978b8803SAndrew Geissler     getBootProgress(asyncResp);
3331b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
3332472bd202SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
333351709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3334c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
33359dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3336797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3337c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3338a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3339a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3340a6349918SAppaRao Puli #endif
33411981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
33423a2d0424SChris Cain     getPowerMode(asyncResp);
334337bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3344c1e219d5SEd Tanous }
3345550a6bf8SJiaqing Zhao 
3346c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3347c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
334822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3349c1e219d5SEd Tanous     const std::string& systemName)
3350c1e219d5SEd Tanous {
33513ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
335245ca1b86SEd Tanous     {
335345ca1b86SEd Tanous         return;
335445ca1b86SEd Tanous     }
33557f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
33567f3e84a1SEd Tanous     {
33577f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
33587f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
33597f3e84a1SEd Tanous                                    systemName);
33607f3e84a1SEd Tanous         return;
33617f3e84a1SEd Tanous     }
336222d268cbSEd Tanous     if (systemName != "system")
336322d268cbSEd Tanous     {
336422d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
336522d268cbSEd Tanous                                    systemName);
336622d268cbSEd Tanous         return;
336722d268cbSEd Tanous     }
336822d268cbSEd Tanous 
3369dd60b9edSEd Tanous     asyncResp->res.addHeader(
3370dd60b9edSEd Tanous         boost::beast::http::field::link,
3371dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3372dd60b9edSEd Tanous 
33739f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3374cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
337598e386ecSGunnar Mills     std::optional<std::string> assetTag;
3376c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
33773a2d0424SChris Cain     std::optional<std::string> powerMode;
3378550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3379550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3380550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3381550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3382550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3383550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3384797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3385550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
33869dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3387550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3388550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3389550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3390550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3391550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3392550a6bf8SJiaqing Zhao 
3393550a6bf8SJiaqing Zhao     // clang-format off
339415ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3395550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3396550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
33977e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3398550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3399550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3400550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3401550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3402550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3403550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3404550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3405550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3406550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3407797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3408550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
34099dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3410550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3411550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3412550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3413550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3414550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
34156617338dSEd Tanous                 {
34166617338dSEd Tanous                     return;
34176617338dSEd Tanous                 }
3418550a6bf8SJiaqing Zhao     // clang-format on
3419491d8ee7SSantosh Puranik 
34208d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3421c45f0082SYong Li 
342298e386ecSGunnar Mills     if (assetTag)
342398e386ecSGunnar Mills     {
342498e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
342598e386ecSGunnar Mills     }
342698e386ecSGunnar Mills 
3427550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3428c45f0082SYong Li     {
3429f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3430c45f0082SYong Li     }
3431c45f0082SYong Li 
3432cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
343369f35306SGunnar Mills     {
3434002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3435491d8ee7SSantosh Puranik     }
3436550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
343769f35306SGunnar Mills     {
3438550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
343969f35306SGunnar Mills     }
3440ac7e1e0bSAli Ahmed 
3441797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3442797d5daeSCorey Hardesty     {
3443797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3444797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3445797d5daeSCorey Hardesty     }
3446797d5daeSCorey Hardesty 
3447550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3448ac7e1e0bSAli Ahmed     {
3449c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
345069f35306SGunnar Mills     }
3451265c1602SJohnathan Mantey 
34529dcfe8c1SAlbert Zhang     if (stopBootOnFault)
34539dcfe8c1SAlbert Zhang     {
34549dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
34559dcfe8c1SAlbert Zhang     }
34569dcfe8c1SAlbert Zhang 
34579f8bfa7cSGunnar Mills     if (locationIndicatorActive)
34589f8bfa7cSGunnar Mills     {
3459002d39b4SEd Tanous         setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
34609f8bfa7cSGunnar Mills     }
34619f8bfa7cSGunnar Mills 
34627e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
34637e860f15SJohn Edward Broadbent     // passed
34649712f8acSEd Tanous     if (indicatorLed)
34656617338dSEd Tanous     {
3466f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3467002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3468d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3469d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
34706617338dSEd Tanous     }
3471c6a620f2SGeorge Liu 
3472c6a620f2SGeorge Liu     if (powerRestorePolicy)
3473c6a620f2SGeorge Liu     {
34744e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3475c6a620f2SGeorge Liu     }
34763a2d0424SChris Cain 
34773a2d0424SChris Cain     if (powerMode)
34783a2d0424SChris Cain     {
34793a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
34803a2d0424SChris Cain     }
348137bbf98cSChris Cain 
3482c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
348337bbf98cSChris Cain     {
3484002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3485002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
348637bbf98cSChris Cain     }
3487c1e219d5SEd Tanous }
34881cb1a9e6SAppaRao Puli 
348938c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3490dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
34917f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3492c1e219d5SEd Tanous     const std::string& /*systemName*/)
3493dd60b9edSEd Tanous {
3494dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3495dd60b9edSEd Tanous     {
3496dd60b9edSEd Tanous         return;
3497dd60b9edSEd Tanous     }
3498dd60b9edSEd Tanous     asyncResp->res.addHeader(
3499dd60b9edSEd Tanous         boost::beast::http::field::link,
3500dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3501dd60b9edSEd Tanous }
3502c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3503c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
350422d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3505c1e219d5SEd Tanous     const std::string& systemName)
3506c1e219d5SEd Tanous {
35073ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
350845ca1b86SEd Tanous     {
350945ca1b86SEd Tanous         return;
351045ca1b86SEd Tanous     }
35117f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
35127f3e84a1SEd Tanous     {
35137f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
35147f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
35157f3e84a1SEd Tanous                                    systemName);
35167f3e84a1SEd Tanous         return;
35177f3e84a1SEd Tanous     }
3518746b56f3SAsmitha Karunanithi 
3519746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3520746b56f3SAsmitha Karunanithi     {
3521746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3522746b56f3SAsmitha Karunanithi         return;
3523746b56f3SAsmitha Karunanithi     }
3524746b56f3SAsmitha Karunanithi 
352522d268cbSEd Tanous     if (systemName != "system")
352622d268cbSEd Tanous     {
352722d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
352822d268cbSEd Tanous                                    systemName);
352922d268cbSEd Tanous         return;
353022d268cbSEd Tanous     }
353122d268cbSEd Tanous 
3532dd60b9edSEd Tanous     asyncResp->res.addHeader(
3533dd60b9edSEd Tanous         boost::beast::http::field::link,
3534dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
35351476687dSEd Tanous 
35361476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
35371476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3538c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
35391476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
35401476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
35413215e700SNan Zhou 
35423215e700SNan Zhou     nlohmann::json::array_t parameters;
35433215e700SNan Zhou     nlohmann::json::object_t parameter;
35443215e700SNan Zhou 
35453215e700SNan Zhou     parameter["Name"] = "ResetType";
35463215e700SNan Zhou     parameter["Required"] = true;
35473215e700SNan Zhou     parameter["DataType"] = "String";
35483215e700SNan Zhou     nlohmann::json::array_t allowableValues;
35493215e700SNan Zhou     allowableValues.emplace_back("On");
35503215e700SNan Zhou     allowableValues.emplace_back("ForceOff");
35513215e700SNan Zhou     allowableValues.emplace_back("ForceOn");
35523215e700SNan Zhou     allowableValues.emplace_back("ForceRestart");
35533215e700SNan Zhou     allowableValues.emplace_back("GracefulRestart");
35543215e700SNan Zhou     allowableValues.emplace_back("GracefulShutdown");
35553215e700SNan Zhou     allowableValues.emplace_back("PowerCycle");
35563215e700SNan Zhou     allowableValues.emplace_back("Nmi");
35573215e700SNan Zhou     parameter["AllowableValues"] = std::move(allowableValues);
35583215e700SNan Zhou     parameters.emplace_back(std::move(parameter));
35593215e700SNan Zhou 
35603215e700SNan Zhou     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3561c1e219d5SEd Tanous }
3562c1e219d5SEd Tanous /**
3563c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3564c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3565c1e219d5SEd Tanous  */
3566100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3567c1e219d5SEd Tanous {
3568100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3569100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3570100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3571100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3572100afe56SEd Tanous 
3573100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3574100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3575100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3576100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3577100afe56SEd Tanous 
3578100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3579100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3580100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3581100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3582100afe56SEd Tanous 
3583100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3584100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3585100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3586100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3587100afe56SEd Tanous 
3588100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3589100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3590100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3591100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3592100afe56SEd Tanous 
3593100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3594100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3595100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3596100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3597100afe56SEd Tanous 
3598c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3599c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3600c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3601c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3602c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3603c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3604c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3605c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36061cb1a9e6SAppaRao Puli }
3607c5b2abe0SLewanczyk, Dawid } // namespace redfish
3608