xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision a974c132c8eaa591acaa92019f9b0088b4815ff1)
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 {
6762598e31SEd Tanous     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 {
9662598e31SEd Tanous     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 {
12662598e31SEd Tanous     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 {
14762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
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         {
19662598e31SEd Tanous             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             {
21562598e31SEd Tanous                 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         {
23662598e31SEd Tanous             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 {
26062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
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                 {
27562598e31SEd Tanous                     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"];
300dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
301cf0e004cSNinad Palsule         if (preValue == nullptr)
302cf0e004cSNinad Palsule         {
303ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
304dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
305cf0e004cSNinad Palsule         }
306cf0e004cSNinad Palsule         else
307cf0e004cSNinad Palsule         {
308ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
309dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
310dfb2b408SPriyanga 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         {
34162598e31SEd Tanous             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 
349*a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
350*a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
351*a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3521abe55efSEd Tanous {
353*a974c132SLakshmi Yadlapati     if (ec)
354*a974c132SLakshmi Yadlapati     {
355*a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
356*a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
357*a974c132SLakshmi Yadlapati         return;
358*a974c132SLakshmi Yadlapati     }
359*a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
360*a974c132SLakshmi Yadlapati 
361*a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
362*a974c132SLakshmi Yadlapati 
363*a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
364*a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
365*a974c132SLakshmi Yadlapati 
366*a974c132SLakshmi Yadlapati     if (!success)
367*a974c132SLakshmi Yadlapati     {
368*a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
369*a974c132SLakshmi Yadlapati         return;
370*a974c132SLakshmi Yadlapati     }
371*a974c132SLakshmi Yadlapati 
372*a974c132SLakshmi Yadlapati     if (uUID != nullptr)
373*a974c132SLakshmi Yadlapati     {
374*a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
375*a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
376*a974c132SLakshmi Yadlapati         {
377*a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
378*a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
379*a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
380*a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
381*a974c132SLakshmi Yadlapati         }
382*a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
383*a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
384*a974c132SLakshmi Yadlapati     }
385*a974c132SLakshmi Yadlapati }
386*a974c132SLakshmi Yadlapati 
387*a974c132SLakshmi Yadlapati inline void
388*a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
389*a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
390*a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
391*a974c132SLakshmi Yadlapati {
392*a974c132SLakshmi Yadlapati     if (ec)
393*a974c132SLakshmi Yadlapati     {
394*a974c132SLakshmi Yadlapati         // doesn't have to include this
395*a974c132SLakshmi Yadlapati         // interface
396*a974c132SLakshmi Yadlapati         return;
397*a974c132SLakshmi Yadlapati     }
398*a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
399*a974c132SLakshmi Yadlapati 
400*a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
401*a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
402*a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
403*a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
404*a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
405*a974c132SLakshmi Yadlapati 
406*a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
407*a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
408*a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
409*a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
410*a974c132SLakshmi Yadlapati 
411*a974c132SLakshmi Yadlapati     if (!success)
412*a974c132SLakshmi Yadlapati     {
413*a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
414*a974c132SLakshmi Yadlapati         return;
415*a974c132SLakshmi Yadlapati     }
416*a974c132SLakshmi Yadlapati 
417*a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
418*a974c132SLakshmi Yadlapati     {
419*a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
420*a974c132SLakshmi Yadlapati     }
421*a974c132SLakshmi Yadlapati 
422*a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
423*a974c132SLakshmi Yadlapati     {
424*a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
425*a974c132SLakshmi Yadlapati     }
426*a974c132SLakshmi Yadlapati 
427*a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
428*a974c132SLakshmi Yadlapati     {
429*a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
430*a974c132SLakshmi Yadlapati     }
431*a974c132SLakshmi Yadlapati 
432*a974c132SLakshmi Yadlapati     if (model != nullptr)
433*a974c132SLakshmi Yadlapati     {
434*a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
435*a974c132SLakshmi Yadlapati     }
436*a974c132SLakshmi Yadlapati 
437*a974c132SLakshmi Yadlapati     if (subModel != nullptr)
438*a974c132SLakshmi Yadlapati     {
439*a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
440*a974c132SLakshmi Yadlapati     }
441*a974c132SLakshmi Yadlapati 
442*a974c132SLakshmi Yadlapati     // Grab the bios version
443*a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
444*a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
445*a974c132SLakshmi Yadlapati }
446*a974c132SLakshmi Yadlapati 
447*a974c132SLakshmi Yadlapati inline void
448*a974c132SLakshmi Yadlapati     afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
449*a974c132SLakshmi Yadlapati                      const boost::system::error_code& ec,
450*a974c132SLakshmi Yadlapati                      const std::string& value)
451*a974c132SLakshmi Yadlapati {
452*a974c132SLakshmi Yadlapati     if (ec)
453*a974c132SLakshmi Yadlapati     {
454*a974c132SLakshmi Yadlapati         // doesn't have to include this
455*a974c132SLakshmi Yadlapati         // interface
456*a974c132SLakshmi Yadlapati         return;
457*a974c132SLakshmi Yadlapati     }
458*a974c132SLakshmi Yadlapati 
459*a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
460*a974c132SLakshmi Yadlapati }
461*a974c132SLakshmi Yadlapati 
462*a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
463*a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
464*a974c132SLakshmi Yadlapati     const std::shared_ptr<HealthPopulate>& systemHealth,
465*a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
466*a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
467*a974c132SLakshmi Yadlapati {
4681abe55efSEd Tanous     if (ec)
4691abe55efSEd Tanous     {
470b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
471ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
472c5b2abe0SLewanczyk, Dawid         return;
473c5b2abe0SLewanczyk, Dawid     }
474c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
475002d39b4SEd Tanous     for (const std::pair<
476002d39b4SEd Tanous              std::string,
477002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4781214b7e7SGunnar Mills              object : subtree)
4791abe55efSEd Tanous     {
480c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
48162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
482002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4831214b7e7SGunnar Mills             connectionNames = object.second;
48426f6976fSEd Tanous         if (connectionNames.empty())
4851abe55efSEd Tanous         {
486c5b2abe0SLewanczyk, Dawid             continue;
487c5b2abe0SLewanczyk, Dawid         }
488029573d4SEd Tanous 
4895fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
4905fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
4915bc2dc8eSJames Feist 
4925fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
4935fd0aafbSNinad Palsule         {
4945fd0aafbSNinad Palsule             memoryHealth = std::make_shared<HealthPopulate>(
495ac106bf6SEd Tanous                 asyncResp, "/MemorySummary/Status"_json_pointer);
4965fd0aafbSNinad Palsule             systemHealth->children.emplace_back(memoryHealth);
4975bc2dc8eSJames Feist 
49813451e39SWilly Tu             if constexpr (bmcwebEnableHealthPopulate)
49913451e39SWilly Tu             {
5005fd0aafbSNinad Palsule                 cpuHealth = std::make_shared<HealthPopulate>(
501ac106bf6SEd Tanous                     asyncResp, "/ProcessorSummary/Status"_json_pointer);
5025fd0aafbSNinad Palsule 
5035bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
50413451e39SWilly Tu             }
5055fd0aafbSNinad Palsule         }
5065bc2dc8eSJames Feist 
5076c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
5086c34de48SEd Tanous         // BiosVer
50904a258f4SEd Tanous         for (const auto& connection : connectionNames)
5101abe55efSEd Tanous         {
51104a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
5121abe55efSEd Tanous             {
513*a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
5141abe55efSEd Tanous                 {
51562598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
5169d3ae10eSAlpana Kumari 
517ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
5185bc2dc8eSJames Feist 
5195fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5205fd0aafbSNinad Palsule                     {
5215bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
5221abe55efSEd Tanous                     }
5235fd0aafbSNinad Palsule                 }
52404a258f4SEd Tanous                 else if (interfaceName ==
52504a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
5261abe55efSEd Tanous                 {
52762598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
52857e8c9beSAlpana Kumari 
529ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
5305bc2dc8eSJames Feist 
5315fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5325fd0aafbSNinad Palsule                     {
5335bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
5341abe55efSEd Tanous                     }
5355fd0aafbSNinad Palsule                 }
536002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
5371abe55efSEd Tanous                 {
53862598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
539bc1d29deSKrzysztof Grobelny 
540bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
541*a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
542*a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
543ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
544b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
5451214b7e7SGunnar Mills                                         properties) {
546*a974c132SLakshmi Yadlapati                         afterGetUUID(asyncResp, ec3, properties);
547bc1d29deSKrzysztof Grobelny                     });
548c5b2abe0SLewanczyk, Dawid                 }
549029573d4SEd Tanous                 else if (interfaceName ==
550029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
5511abe55efSEd Tanous                 {
552bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
553*a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
554bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
555*a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
556b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
557*a974c132SLakshmi Yadlapati                                         properties) {
558*a974c132SLakshmi Yadlapati                         afterGetInventory(asyncResp, ec3, properties);
559bc1d29deSKrzysztof Grobelny                     });
560e4a4b9a9SJames Feist 
5611e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
562*a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
5631e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
5641e1e598dSJonathan Doman                         "AssetTag",
5651e1e598dSJonathan Doman                         "AssetTag",
566*a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
567*a974c132SLakshmi Yadlapati                 }
568*a974c132SLakshmi Yadlapati             }
569*a974c132SLakshmi Yadlapati         }
570*a974c132SLakshmi Yadlapati     }
571*a974c132SLakshmi Yadlapati }
572*a974c132SLakshmi Yadlapati 
573*a974c132SLakshmi Yadlapati /*
574*a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
575*a974c132SLakshmi Yadlapati  *
576*a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
577*a974c132SLakshmi Yadlapati  * @param[in] systemHealth  Shared HealthPopulate pointer
578*a974c132SLakshmi Yadlapati  *
579*a974c132SLakshmi Yadlapati  * @return None.
580*a974c132SLakshmi Yadlapati  */
581*a974c132SLakshmi Yadlapati inline void
582*a974c132SLakshmi Yadlapati     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
583*a974c132SLakshmi Yadlapati                       const std::shared_ptr<HealthPopulate>& systemHealth)
584e4a4b9a9SJames Feist {
585*a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
586*a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
587*a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
588*a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
589*a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
590*a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
591*a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
592*a974c132SLakshmi Yadlapati     };
593*a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
594*a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
595*a974c132SLakshmi Yadlapati         std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
596c5b2abe0SLewanczyk, Dawid }
597c5b2abe0SLewanczyk, Dawid 
598c5b2abe0SLewanczyk, Dawid /**
599c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
600c5b2abe0SLewanczyk, Dawid  *
601ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
602c5b2abe0SLewanczyk, Dawid  *
603c5b2abe0SLewanczyk, Dawid  * @return None.
604c5b2abe0SLewanczyk, Dawid  */
605ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
6061abe55efSEd Tanous {
60762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
6081e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6091e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6101e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6111e1e598dSJonathan Doman         "CurrentHostState",
612ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
6131e1e598dSJonathan Doman                     const std::string& hostState) {
6141abe55efSEd Tanous         if (ec)
6151abe55efSEd Tanous         {
61622228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
61722228c28SAndrew Geissler             {
61822228c28SAndrew Geissler                 // Service not available, no error, just don't return
61922228c28SAndrew Geissler                 // host state info
62062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Service not available {}", ec);
62122228c28SAndrew Geissler                 return;
62222228c28SAndrew Geissler             }
62362598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
624ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
625c5b2abe0SLewanczyk, Dawid             return;
626c5b2abe0SLewanczyk, Dawid         }
6276617338dSEd Tanous 
62862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Host state: {}", hostState);
629c5b2abe0SLewanczyk, Dawid         // Verify Host State
6301e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6311abe55efSEd Tanous         {
632ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
633ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
6341abe55efSEd Tanous         }
6351e1e598dSJonathan Doman         else if (hostState ==
6360fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6378c888608SGunnar Mills         {
638ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
639ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
6408c888608SGunnar Mills         }
6411e1e598dSJonathan Doman         else if (hostState ==
6420fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
64383935af9SAndrew Geissler         {
644ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
645ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
64683935af9SAndrew Geissler         }
6470fda0f12SGeorge Liu         else if (
6481e1e598dSJonathan Doman             hostState ==
6490fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6501a2a1437SAndrew Geissler         {
651ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
652ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
6531a2a1437SAndrew Geissler         }
654002d39b4SEd Tanous         else if (hostState ==
6550fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6561a2a1437SAndrew Geissler         {
657ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
658ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
6591a2a1437SAndrew Geissler         }
6601abe55efSEd Tanous         else
6611abe55efSEd Tanous         {
662ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
663ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
664c5b2abe0SLewanczyk, Dawid         }
6651e1e598dSJonathan Doman     });
666c5b2abe0SLewanczyk, Dawid }
667c5b2abe0SLewanczyk, Dawid 
668c5b2abe0SLewanczyk, Dawid /**
669786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
670491d8ee7SSantosh Puranik  *
671491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
672491d8ee7SSantosh Puranik  *
673491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
674491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
675491d8ee7SSantosh Puranik  */
67623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
677491d8ee7SSantosh Puranik {
678491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
679491d8ee7SSantosh Puranik     {
680491d8ee7SSantosh Puranik         return "None";
681491d8ee7SSantosh Puranik     }
6823174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
683491d8ee7SSantosh Puranik     {
684491d8ee7SSantosh Puranik         return "Hdd";
685491d8ee7SSantosh Puranik     }
6863174e4dfSEd Tanous     if (dbusSource ==
687a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
688491d8ee7SSantosh Puranik     {
689491d8ee7SSantosh Puranik         return "Cd";
690491d8ee7SSantosh Puranik     }
6913174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
692491d8ee7SSantosh Puranik     {
693491d8ee7SSantosh Puranik         return "Pxe";
694491d8ee7SSantosh Puranik     }
6953174e4dfSEd Tanous     if (dbusSource ==
696944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6979f16b2c1SJennifer Lee     {
6989f16b2c1SJennifer Lee         return "Usb";
6999f16b2c1SJennifer Lee     }
700491d8ee7SSantosh Puranik     return "";
701491d8ee7SSantosh Puranik }
702491d8ee7SSantosh Puranik 
703491d8ee7SSantosh Puranik /**
704cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
705cd9a4666SKonstantin Aladyshev  *
706cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
707cd9a4666SKonstantin Aladyshev  *
708cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
709cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
710cd9a4666SKonstantin Aladyshev  */
711cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
712cd9a4666SKonstantin Aladyshev {
713cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
714cd9a4666SKonstantin Aladyshev     {
715cd9a4666SKonstantin Aladyshev         return "Legacy";
716cd9a4666SKonstantin Aladyshev     }
717cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
718cd9a4666SKonstantin Aladyshev     {
719cd9a4666SKonstantin Aladyshev         return "UEFI";
720cd9a4666SKonstantin Aladyshev     }
721cd9a4666SKonstantin Aladyshev     return "";
722cd9a4666SKonstantin Aladyshev }
723cd9a4666SKonstantin Aladyshev 
724cd9a4666SKonstantin Aladyshev /**
725786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
726491d8ee7SSantosh Puranik  *
727491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
728491d8ee7SSantosh Puranik  *
729491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
730491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
731491d8ee7SSantosh Puranik  */
73223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
733491d8ee7SSantosh Puranik {
734491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
735491d8ee7SSantosh Puranik     {
736491d8ee7SSantosh Puranik         return "None";
737491d8ee7SSantosh Puranik     }
7383174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
739491d8ee7SSantosh Puranik     {
740491d8ee7SSantosh Puranik         return "Diags";
741491d8ee7SSantosh Puranik     }
7423174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
743491d8ee7SSantosh Puranik     {
744491d8ee7SSantosh Puranik         return "BiosSetup";
745491d8ee7SSantosh Puranik     }
746491d8ee7SSantosh Puranik     return "";
747491d8ee7SSantosh Puranik }
748491d8ee7SSantosh Puranik 
749491d8ee7SSantosh Puranik /**
750e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
751e43914b3SAndrew Geissler  *
752e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
753e43914b3SAndrew Geissler  *
754e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
755e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
756e43914b3SAndrew Geissler  */
757e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
758e43914b3SAndrew Geissler {
759e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
760e43914b3SAndrew Geissler     // enum
761e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
762e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
763e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
764e43914b3SAndrew Geissler     {
765e43914b3SAndrew Geissler         rfBpLastState = "None";
766e43914b3SAndrew Geissler     }
767e43914b3SAndrew Geissler     else if (dbusBootProgress ==
768e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
769e43914b3SAndrew Geissler              "PrimaryProcInit")
770e43914b3SAndrew Geissler     {
771e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
772e43914b3SAndrew Geissler     }
773e43914b3SAndrew Geissler     else if (dbusBootProgress ==
774e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
775e43914b3SAndrew Geissler              "BusInit")
776e43914b3SAndrew Geissler     {
777e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
778e43914b3SAndrew Geissler     }
779e43914b3SAndrew Geissler     else if (dbusBootProgress ==
780e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
781e43914b3SAndrew Geissler              "MemoryInit")
782e43914b3SAndrew Geissler     {
783e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
784e43914b3SAndrew Geissler     }
785e43914b3SAndrew Geissler     else if (dbusBootProgress ==
786e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
787e43914b3SAndrew Geissler              "SecondaryProcInit")
788e43914b3SAndrew Geissler     {
789e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
790e43914b3SAndrew Geissler     }
791e43914b3SAndrew Geissler     else if (dbusBootProgress ==
792e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
793e43914b3SAndrew Geissler              "PCIInit")
794e43914b3SAndrew Geissler     {
795e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
796e43914b3SAndrew Geissler     }
797e43914b3SAndrew Geissler     else if (dbusBootProgress ==
798e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
799e43914b3SAndrew Geissler              "SystemSetup")
800e43914b3SAndrew Geissler     {
801e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
802e43914b3SAndrew Geissler     }
803e43914b3SAndrew Geissler     else if (dbusBootProgress ==
804e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
805e43914b3SAndrew Geissler              "SystemInitComplete")
806e43914b3SAndrew Geissler     {
807e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
808e43914b3SAndrew Geissler     }
809e43914b3SAndrew Geissler     else if (dbusBootProgress ==
810e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
811e43914b3SAndrew Geissler              "OSStart")
812e43914b3SAndrew Geissler     {
813e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
814e43914b3SAndrew Geissler     }
815e43914b3SAndrew Geissler     else if (dbusBootProgress ==
816e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
817e43914b3SAndrew Geissler              "OSRunning")
818e43914b3SAndrew Geissler     {
819e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
820e43914b3SAndrew Geissler     }
821e43914b3SAndrew Geissler     else
822e43914b3SAndrew Geissler     {
82362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
824e43914b3SAndrew Geissler         // Just return the default
825e43914b3SAndrew Geissler     }
826e43914b3SAndrew Geissler     return rfBpLastState;
827e43914b3SAndrew Geissler }
828e43914b3SAndrew Geissler 
829e43914b3SAndrew Geissler /**
830786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
831491d8ee7SSantosh Puranik  *
832491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
833944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
834944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
835491d8ee7SSantosh Puranik  *
836944ffaf9SJohnathan Mantey  * @return Integer error code.
837491d8ee7SSantosh Puranik  */
838ac106bf6SEd Tanous inline int
839ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
840ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
841ac106bf6SEd Tanous                          std::string& bootMode)
842491d8ee7SSantosh Puranik {
843c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
844c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
845944ffaf9SJohnathan Mantey 
846491d8ee7SSantosh Puranik     if (rfSource == "None")
847491d8ee7SSantosh Puranik     {
848944ffaf9SJohnathan Mantey         return 0;
849491d8ee7SSantosh Puranik     }
8503174e4dfSEd Tanous     if (rfSource == "Pxe")
851491d8ee7SSantosh Puranik     {
852944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
853944ffaf9SJohnathan Mantey     }
854944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
855944ffaf9SJohnathan Mantey     {
856944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
857944ffaf9SJohnathan Mantey     }
858944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
859944ffaf9SJohnathan Mantey     {
860944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
861944ffaf9SJohnathan Mantey     }
862944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
863944ffaf9SJohnathan Mantey     {
864944ffaf9SJohnathan Mantey         bootSource =
865944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
866944ffaf9SJohnathan Mantey     }
867944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
868944ffaf9SJohnathan Mantey     {
869944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
870491d8ee7SSantosh Puranik     }
8719f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8729f16b2c1SJennifer Lee     {
873944ffaf9SJohnathan Mantey         bootSource =
874944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8759f16b2c1SJennifer Lee     }
876491d8ee7SSantosh Puranik     else
877491d8ee7SSantosh Puranik     {
87862598e31SEd Tanous         BMCWEB_LOG_DEBUG(
87962598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
88062598e31SEd Tanous             bootSource);
881ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
882944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
883944ffaf9SJohnathan Mantey         return -1;
884491d8ee7SSantosh Puranik     }
885944ffaf9SJohnathan Mantey     return 0;
886491d8ee7SSantosh Puranik }
8871981771bSAli Ahmed 
888978b8803SAndrew Geissler /**
889978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
890978b8803SAndrew Geissler  *
891ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
892978b8803SAndrew Geissler  *
893978b8803SAndrew Geissler  * @return None.
894978b8803SAndrew Geissler  */
895ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
896978b8803SAndrew Geissler {
8971e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8981e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8991e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
9001e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
901ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9021e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
903978b8803SAndrew Geissler         if (ec)
904978b8803SAndrew Geissler         {
905978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
906978b8803SAndrew Geissler             // not found
907978b8803SAndrew Geissler             return;
908978b8803SAndrew Geissler         }
909978b8803SAndrew Geissler 
91062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
911978b8803SAndrew Geissler 
912ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
913e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9141e1e598dSJonathan Doman     });
915978b8803SAndrew Geissler }
916491d8ee7SSantosh Puranik 
917491d8ee7SSantosh Puranik /**
918b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
919b6d5d45cSHieu Huynh  *
920ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
921b6d5d45cSHieu Huynh  *
922b6d5d45cSHieu Huynh  * @return None.
923b6d5d45cSHieu Huynh  */
924b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
925ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
926b6d5d45cSHieu Huynh {
927b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
928b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
929b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
930b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
931ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
932b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
933b6d5d45cSHieu Huynh         if (ec)
934b6d5d45cSHieu Huynh         {
93562598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
936b6d5d45cSHieu Huynh             return;
937b6d5d45cSHieu Huynh         }
938b6d5d45cSHieu Huynh 
939b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
940b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
941b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
942b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
943b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
944b6d5d45cSHieu Huynh 
945b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
946ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
947b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
948b6d5d45cSHieu Huynh     });
949b6d5d45cSHieu Huynh }
950b6d5d45cSHieu Huynh 
951b6d5d45cSHieu Huynh /**
952c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
953cd9a4666SKonstantin Aladyshev  *
954ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
955cd9a4666SKonstantin Aladyshev  *
956cd9a4666SKonstantin Aladyshev  * @return None.
957cd9a4666SKonstantin Aladyshev  */
958cd9a4666SKonstantin Aladyshev 
959ac106bf6SEd Tanous inline void
960ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
961cd9a4666SKonstantin Aladyshev {
9621e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9631e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9641e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9651e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
966ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9671e1e598dSJonathan Doman                     const std::string& bootType) {
968cd9a4666SKonstantin Aladyshev         if (ec)
969cd9a4666SKonstantin Aladyshev         {
970cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
971cd9a4666SKonstantin Aladyshev             return;
972cd9a4666SKonstantin Aladyshev         }
973cd9a4666SKonstantin Aladyshev 
97462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
975cd9a4666SKonstantin Aladyshev 
976ac106bf6SEd Tanous         asyncResp->res
977ac106bf6SEd Tanous             .jsonValue["Boot"]
978002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
979613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
980cd9a4666SKonstantin Aladyshev 
9811e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
982cd9a4666SKonstantin Aladyshev         if (rfType.empty())
983cd9a4666SKonstantin Aladyshev         {
984ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
985cd9a4666SKonstantin Aladyshev             return;
986cd9a4666SKonstantin Aladyshev         }
987cd9a4666SKonstantin Aladyshev 
988ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9891e1e598dSJonathan Doman     });
990cd9a4666SKonstantin Aladyshev }
991cd9a4666SKonstantin Aladyshev 
992cd9a4666SKonstantin Aladyshev /**
993c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
994491d8ee7SSantosh Puranik  *
995ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
996491d8ee7SSantosh Puranik  *
997491d8ee7SSantosh Puranik  * @return None.
998491d8ee7SSantosh Puranik  */
999c21865c4SKonstantin Aladyshev 
1000ac106bf6SEd Tanous inline void
1001ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1002491d8ee7SSantosh Puranik {
10031e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10041e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10051e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10061e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1007ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10081e1e598dSJonathan Doman                     const std::string& bootModeStr) {
1009491d8ee7SSantosh Puranik         if (ec)
1010491d8ee7SSantosh Puranik         {
1011b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1012ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1013491d8ee7SSantosh Puranik             return;
1014491d8ee7SSantosh Puranik         }
1015491d8ee7SSantosh Puranik 
101662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
1017491d8ee7SSantosh Puranik 
1018ac106bf6SEd Tanous         asyncResp->res
10190fda0f12SGeorge Liu             .jsonValue["Boot"]
1020002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1021002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1022491d8ee7SSantosh Puranik 
10231e1e598dSJonathan Doman         if (bootModeStr !=
1024491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1025491d8ee7SSantosh Puranik         {
10261e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1027491d8ee7SSantosh Puranik             if (!rfMode.empty())
1028491d8ee7SSantosh Puranik             {
1029ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1030491d8ee7SSantosh Puranik                     rfMode;
1031491d8ee7SSantosh Puranik             }
1032491d8ee7SSantosh Puranik         }
10331e1e598dSJonathan Doman     });
1034491d8ee7SSantosh Puranik }
1035491d8ee7SSantosh Puranik 
1036491d8ee7SSantosh Puranik /**
1037c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1038491d8ee7SSantosh Puranik  *
1039ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1040491d8ee7SSantosh Puranik  *
1041491d8ee7SSantosh Puranik  * @return None.
1042491d8ee7SSantosh Puranik  */
1043c21865c4SKonstantin Aladyshev 
1044c21865c4SKonstantin Aladyshev inline void
1045ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1046491d8ee7SSantosh Puranik {
10471e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10481e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10491e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10501e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1051ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10521e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1053491d8ee7SSantosh Puranik         if (ec)
1054491d8ee7SSantosh Puranik         {
10555ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10565ef735c8SNan Zhou             {
10575ef735c8SNan Zhou                 return;
10585ef735c8SNan Zhou             }
1059b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1060ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1061491d8ee7SSantosh Puranik             return;
1062491d8ee7SSantosh Puranik         }
1063491d8ee7SSantosh Puranik 
106462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1065491d8ee7SSantosh Puranik 
10661e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1067491d8ee7SSantosh Puranik         if (!rfSource.empty())
1068491d8ee7SSantosh Puranik         {
1069ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1070ac106bf6SEd Tanous                 rfSource;
1071491d8ee7SSantosh Puranik         }
1072cd9a4666SKonstantin Aladyshev 
1073cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1074cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1075ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10761e1e598dSJonathan Doman     });
1077491d8ee7SSantosh Puranik }
1078491d8ee7SSantosh Puranik 
1079491d8ee7SSantosh Puranik /**
1080c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1081c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1082c21865c4SKonstantin Aladyshev  * state
1083491d8ee7SSantosh Puranik  *
1084ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1085491d8ee7SSantosh Puranik  *
1086491d8ee7SSantosh Puranik  * @return None.
1087491d8ee7SSantosh Puranik  */
1088491d8ee7SSantosh Puranik 
1089ac106bf6SEd Tanous inline void processBootOverrideEnable(
1090ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1091c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1092c21865c4SKonstantin Aladyshev {
1093c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1094c21865c4SKonstantin Aladyshev     {
1095ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1096ac106bf6SEd Tanous             "Disabled";
1097c21865c4SKonstantin Aladyshev         return;
1098c21865c4SKonstantin Aladyshev     }
1099c21865c4SKonstantin Aladyshev 
1100c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1101c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
11021e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11031e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11041e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
11051e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1106ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1107491d8ee7SSantosh Puranik         if (ec)
1108491d8ee7SSantosh Puranik         {
1109b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1110ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1111491d8ee7SSantosh Puranik             return;
1112491d8ee7SSantosh Puranik         }
1113491d8ee7SSantosh Puranik 
1114c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1115c21865c4SKonstantin Aladyshev         {
1116ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1117ac106bf6SEd Tanous                 "Once";
1118c21865c4SKonstantin Aladyshev         }
1119c21865c4SKonstantin Aladyshev         else
1120c21865c4SKonstantin Aladyshev         {
1121ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1122c21865c4SKonstantin Aladyshev                 "Continuous";
1123c21865c4SKonstantin Aladyshev         }
11241e1e598dSJonathan Doman     });
1125491d8ee7SSantosh Puranik }
1126491d8ee7SSantosh Puranik 
1127491d8ee7SSantosh Puranik /**
1128c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1129c21865c4SKonstantin Aladyshev  *
1130ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1131c21865c4SKonstantin Aladyshev  *
1132c21865c4SKonstantin Aladyshev  * @return None.
1133c21865c4SKonstantin Aladyshev  */
1134c21865c4SKonstantin Aladyshev 
1135c21865c4SKonstantin Aladyshev inline void
1136ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1137c21865c4SKonstantin Aladyshev {
11381e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11391e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11401e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11411e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1142ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
11431e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1144c21865c4SKonstantin Aladyshev         if (ec)
1145c21865c4SKonstantin Aladyshev         {
11465ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11475ef735c8SNan Zhou             {
11485ef735c8SNan Zhou                 return;
11495ef735c8SNan Zhou             }
1150b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1151ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1152c21865c4SKonstantin Aladyshev             return;
1153c21865c4SKonstantin Aladyshev         }
1154c21865c4SKonstantin Aladyshev 
1155ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11561e1e598dSJonathan Doman     });
1157c21865c4SKonstantin Aladyshev }
1158c21865c4SKonstantin Aladyshev 
1159c21865c4SKonstantin Aladyshev /**
1160c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1161c21865c4SKonstantin Aladyshev  *
1162ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1163c21865c4SKonstantin Aladyshev  *
1164c21865c4SKonstantin Aladyshev  * @return None.
1165c21865c4SKonstantin Aladyshev  */
1166ac106bf6SEd Tanous inline void
1167ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1168c21865c4SKonstantin Aladyshev {
116962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1170c21865c4SKonstantin Aladyshev 
1171ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1172ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1173ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1174c21865c4SKonstantin Aladyshev }
1175c21865c4SKonstantin Aladyshev 
1176c21865c4SKonstantin Aladyshev /**
1177c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1178c0557e1aSGunnar Mills  *
1179c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1180c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1181c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1182c0557e1aSGunnar Mills  * last power operation time.
1183c0557e1aSGunnar Mills  *
1184ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1185c0557e1aSGunnar Mills  *
1186c0557e1aSGunnar Mills  * @return None.
1187c0557e1aSGunnar Mills  */
1188ac106bf6SEd Tanous inline void
1189ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1190c0557e1aSGunnar Mills {
119162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1192c0557e1aSGunnar Mills 
11931e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11941e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11951e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11961e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1197ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1198ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1199c0557e1aSGunnar Mills         if (ec)
1200c0557e1aSGunnar Mills         {
120162598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1202c0557e1aSGunnar Mills             return;
1203c0557e1aSGunnar Mills         }
1204c0557e1aSGunnar Mills 
1205c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1206c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
12071e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1208c0557e1aSGunnar Mills 
1209c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1210ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
12112b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
12121e1e598dSJonathan Doman     });
1213c0557e1aSGunnar Mills }
1214c0557e1aSGunnar Mills 
1215c0557e1aSGunnar Mills /**
1216797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1217797d5daeSCorey Hardesty  *
1218797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1219797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1220797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1221797d5daeSCorey Hardesty  * dbus.
1222797d5daeSCorey Hardesty  *
1223ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1224797d5daeSCorey Hardesty  *
1225797d5daeSCorey Hardesty  * @return None.
1226797d5daeSCorey Hardesty  */
1227ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1228ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1229797d5daeSCorey Hardesty {
123062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1231797d5daeSCorey Hardesty 
1232797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1233797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1234797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1235797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1236ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1237ac106bf6SEd Tanous             const boost::system::error_code& ec,
1238797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1239797d5daeSCorey Hardesty         if (ec)
1240797d5daeSCorey Hardesty         {
1241797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1242797d5daeSCorey Hardesty             {
124362598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1244ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1245797d5daeSCorey Hardesty             }
1246797d5daeSCorey Hardesty             return;
1247797d5daeSCorey Hardesty         }
1248797d5daeSCorey Hardesty 
1249797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1250797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1251797d5daeSCorey Hardesty 
1252797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1253797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1254797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1255797d5daeSCorey Hardesty 
1256797d5daeSCorey Hardesty         if (!success)
1257797d5daeSCorey Hardesty         {
1258ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1259797d5daeSCorey Hardesty             return;
1260797d5daeSCorey Hardesty         }
1261797d5daeSCorey Hardesty 
1262797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1263797d5daeSCorey Hardesty         {
1264ac106bf6SEd Tanous             asyncResp->res
1265ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1266797d5daeSCorey Hardesty                 *attemptsLeft;
1267797d5daeSCorey Hardesty         }
1268797d5daeSCorey Hardesty 
1269797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1270797d5daeSCorey Hardesty         {
1271ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1272797d5daeSCorey Hardesty                 *retryAttempts;
1273797d5daeSCorey Hardesty         }
1274797d5daeSCorey Hardesty     });
1275797d5daeSCorey Hardesty }
1276797d5daeSCorey Hardesty 
1277797d5daeSCorey Hardesty /**
12786bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12796bd5a8d2SGunnar Mills  *
1280ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12816bd5a8d2SGunnar Mills  *
12826bd5a8d2SGunnar Mills  * @return None.
12836bd5a8d2SGunnar Mills  */
1284797d5daeSCorey Hardesty inline void
1285ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12866bd5a8d2SGunnar Mills {
128762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12886bd5a8d2SGunnar Mills 
12891e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12901e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12911e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12921e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1293ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1294ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12956bd5a8d2SGunnar Mills         if (ec)
12966bd5a8d2SGunnar Mills         {
1297797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1298797d5daeSCorey Hardesty             {
129962598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1300ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1301797d5daeSCorey Hardesty             }
13026bd5a8d2SGunnar Mills             return;
13036bd5a8d2SGunnar Mills         }
13046bd5a8d2SGunnar Mills 
130562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1306e05aec50SEd Tanous         if (autoRebootEnabled)
13076bd5a8d2SGunnar Mills         {
1308ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13096bd5a8d2SGunnar Mills                 "RetryAttempts";
13106bd5a8d2SGunnar Mills         }
13116bd5a8d2SGunnar Mills         else
13126bd5a8d2SGunnar Mills         {
1313ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1314ac106bf6SEd Tanous                 "Disabled";
13156bd5a8d2SGunnar Mills         }
1316ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
131769f35306SGunnar Mills 
131869f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
131969f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
132069f35306SGunnar Mills         // RetryAttempts.
1321ac106bf6SEd Tanous         asyncResp->res
1322ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1323ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
13241e1e598dSJonathan Doman     });
13256bd5a8d2SGunnar Mills }
13266bd5a8d2SGunnar Mills 
13276bd5a8d2SGunnar Mills /**
1328797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1329797d5daeSCorey Hardesty  *
1330ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1331797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1332797d5daeSCorey Hardesty  *
1333797d5daeSCorey Hardesty  *@return None.
1334797d5daeSCorey Hardesty  */
1335797d5daeSCorey Hardesty 
1336ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1337ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1338797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1339797d5daeSCorey Hardesty {
134062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
13419ae226faSGeorge Liu     sdbusplus::asio::setProperty(
13429ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
13439ae226faSGeorge Liu         "/xyz/openbmc_project/state/host0",
13449ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
13459ae226faSGeorge Liu         retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1346797d5daeSCorey Hardesty         if (ec)
1347797d5daeSCorey Hardesty         {
134862598e31SEd Tanous             BMCWEB_LOG_ERROR(
134962598e31SEd Tanous                 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1350ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1351797d5daeSCorey Hardesty             return;
1352797d5daeSCorey Hardesty         }
13539ae226faSGeorge Liu     });
1354797d5daeSCorey Hardesty }
1355797d5daeSCorey Hardesty 
13568d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13578d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13588d69c668SEd Tanous {
13598d69c668SEd Tanous     if (value ==
13608d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13618d69c668SEd Tanous     {
13628d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13638d69c668SEd Tanous     }
13648d69c668SEd Tanous     if (value ==
13658d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13668d69c668SEd Tanous     {
13678d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13688d69c668SEd Tanous     }
13698d69c668SEd Tanous     if (value ==
13703a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13718d69c668SEd Tanous     {
13728d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13738d69c668SEd Tanous     }
13748d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13758d69c668SEd Tanous     {
13768d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13778d69c668SEd Tanous     }
13788d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13798d69c668SEd Tanous }
1380797d5daeSCorey Hardesty /**
1381c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1382c6a620f2SGeorge Liu  *
1383ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1384c6a620f2SGeorge Liu  *
1385c6a620f2SGeorge Liu  * @return None.
1386c6a620f2SGeorge Liu  */
13878d1b46d7Szhanghch05 inline void
1388ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1389c6a620f2SGeorge Liu {
139062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1391c6a620f2SGeorge Liu 
13921e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13931e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13941e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13951e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1396ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13975e7e2dc5SEd Tanous                     const std::string& policy) {
1398c6a620f2SGeorge Liu         if (ec)
1399c6a620f2SGeorge Liu         {
140062598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1401c6a620f2SGeorge Liu             return;
1402c6a620f2SGeorge Liu         }
14038d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
14048d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
14058d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1406c6a620f2SGeorge Liu         {
1407ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1408c6a620f2SGeorge Liu             return;
1409c6a620f2SGeorge Liu         }
1410c6a620f2SGeorge Liu 
14118d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
14121e1e598dSJonathan Doman     });
1413c6a620f2SGeorge Liu }
1414c6a620f2SGeorge Liu 
1415c6a620f2SGeorge Liu /**
14169dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
14179dcfe8c1SAlbert Zhang  *
14189dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
14199dcfe8c1SAlbert Zhang  *
14209dcfe8c1SAlbert Zhang  * @return None.
14219dcfe8c1SAlbert Zhang  */
14229dcfe8c1SAlbert Zhang inline void
14239dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14249dcfe8c1SAlbert Zhang {
142562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
14269dcfe8c1SAlbert Zhang 
14279dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
14289dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
14299dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
14309dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
14319dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
14329dcfe8c1SAlbert Zhang         if (ec)
14339dcfe8c1SAlbert Zhang         {
14349dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
14359dcfe8c1SAlbert Zhang             {
1436b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
14379dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
14389dcfe8c1SAlbert Zhang             }
14399dcfe8c1SAlbert Zhang             return;
14409dcfe8c1SAlbert Zhang         }
14419dcfe8c1SAlbert Zhang 
14429dcfe8c1SAlbert Zhang         if (value)
14439dcfe8c1SAlbert Zhang         {
14449dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
14459dcfe8c1SAlbert Zhang         }
14469dcfe8c1SAlbert Zhang         else
14479dcfe8c1SAlbert Zhang         {
14489dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
14499dcfe8c1SAlbert Zhang         }
14509dcfe8c1SAlbert Zhang     });
14519dcfe8c1SAlbert Zhang }
14529dcfe8c1SAlbert Zhang 
14539dcfe8c1SAlbert Zhang /**
14541981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14551981771bSAli Ahmed  * TPM is required for booting the host.
14561981771bSAli Ahmed  *
1457ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14581981771bSAli Ahmed  *
14591981771bSAli Ahmed  * @return None.
14601981771bSAli Ahmed  */
14611981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1462ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14631981771bSAli Ahmed {
146462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1465e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1466e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1467e99073f5SGeorge Liu     dbus::utility::getSubTree(
1468e99073f5SGeorge Liu         "/", 0, interfaces,
1469ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1470b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14711981771bSAli Ahmed         if (ec)
14721981771bSAli Ahmed         {
147362598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
147462598e31SEd Tanous                              ec);
14751981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14761981771bSAli Ahmed             // error occurs
14771981771bSAli Ahmed             return;
14781981771bSAli Ahmed         }
147926f6976fSEd Tanous         if (subtree.empty())
14801981771bSAli Ahmed         {
14811981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14821981771bSAli Ahmed             // if there is no instance found
14831981771bSAli Ahmed             return;
14841981771bSAli Ahmed         }
14851981771bSAli Ahmed 
14861981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14871981771bSAli Ahmed         if (subtree.size() > 1)
14881981771bSAli Ahmed         {
148962598e31SEd Tanous             BMCWEB_LOG_DEBUG(
149062598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
149162598e31SEd Tanous                 subtree.size());
14921981771bSAli Ahmed             // Throw an internal Error and return
1493ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14941981771bSAli Ahmed             return;
14951981771bSAli Ahmed         }
14961981771bSAli Ahmed 
14971981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14981981771bSAli Ahmed         // field
14991981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15001981771bSAli Ahmed         {
150162598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1502ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15031981771bSAli Ahmed             return;
15041981771bSAli Ahmed         }
15051981771bSAli Ahmed 
15061981771bSAli Ahmed         const std::string& path = subtree[0].first;
15071981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15081981771bSAli Ahmed 
15091981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
15101e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
15111e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
15121e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1513ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1514ac106bf6SEd Tanous                         bool tpmRequired) {
15158a592810SEd Tanous             if (ec2)
15161981771bSAli Ahmed             {
1517b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
151862598e31SEd Tanous                                  ec2);
1519ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15201981771bSAli Ahmed                 return;
15211981771bSAli Ahmed             }
15221981771bSAli Ahmed 
15231e1e598dSJonathan Doman             if (tpmRequired)
15241981771bSAli Ahmed             {
1525ac106bf6SEd Tanous                 asyncResp->res
1526ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15271981771bSAli Ahmed                     "Required";
15281981771bSAli Ahmed             }
15291981771bSAli Ahmed             else
15301981771bSAli Ahmed             {
1531ac106bf6SEd Tanous                 asyncResp->res
1532ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15331981771bSAli Ahmed                     "Disabled";
15341981771bSAli Ahmed             }
15351e1e598dSJonathan Doman         });
1536e99073f5SGeorge Liu     });
15371981771bSAli Ahmed }
15381981771bSAli Ahmed 
15391981771bSAli Ahmed /**
15401c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
15411c05dae3SAli Ahmed  * TPM is required for booting the host.
15421c05dae3SAli Ahmed  *
1543ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
15441c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
15451c05dae3SAli Ahmed  *
15461c05dae3SAli Ahmed  * @return None.
15471c05dae3SAli Ahmed  */
15481c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1549ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
15501c05dae3SAli Ahmed {
155162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1552e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1553e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1554e99073f5SGeorge Liu     dbus::utility::getSubTree(
1555e99073f5SGeorge Liu         "/", 0, interfaces,
1556ac106bf6SEd Tanous         [asyncResp,
1557e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1558e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15591c05dae3SAli Ahmed         if (ec)
15601c05dae3SAli Ahmed         {
1561b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
156262598e31SEd Tanous                              ec);
1563ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15641c05dae3SAli Ahmed             return;
15651c05dae3SAli Ahmed         }
156626f6976fSEd Tanous         if (subtree.empty())
15671c05dae3SAli Ahmed         {
1568ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15691c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15701c05dae3SAli Ahmed             return;
15711c05dae3SAli Ahmed         }
15721c05dae3SAli Ahmed 
15731c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15741c05dae3SAli Ahmed         if (subtree.size() > 1)
15751c05dae3SAli Ahmed         {
157662598e31SEd Tanous             BMCWEB_LOG_DEBUG(
157762598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
157862598e31SEd Tanous                 subtree.size());
15791c05dae3SAli Ahmed             // Throw an internal Error and return
1580ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15811c05dae3SAli Ahmed             return;
15821c05dae3SAli Ahmed         }
15831c05dae3SAli Ahmed 
15841c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15851c05dae3SAli Ahmed         // field
15861c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15871c05dae3SAli Ahmed         {
158862598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1589ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15901c05dae3SAli Ahmed             return;
15911c05dae3SAli Ahmed         }
15921c05dae3SAli Ahmed 
15931c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15941c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15951c05dae3SAli Ahmed 
15961c05dae3SAli Ahmed         if (serv.empty())
15971c05dae3SAli Ahmed         {
159862598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1599ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
16001c05dae3SAli Ahmed             return;
16011c05dae3SAli Ahmed         }
16021c05dae3SAli Ahmed 
16031c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
16049ae226faSGeorge Liu         sdbusplus::asio::setProperty(
16059ae226faSGeorge Liu             *crow::connections::systemBus, serv, path,
16069ae226faSGeorge Liu             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
1607ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
16088a592810SEd Tanous             if (ec2)
16091c05dae3SAli Ahmed             {
1610b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
161162598e31SEd Tanous                     "DBUS response error: Set TrustedModuleRequiredToBoot{}",
161262598e31SEd Tanous                     ec2);
1613ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16141c05dae3SAli Ahmed                 return;
16151c05dae3SAli Ahmed             }
161662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
16179ae226faSGeorge Liu         });
1618e99073f5SGeorge Liu     });
16191c05dae3SAli Ahmed }
16201c05dae3SAli Ahmed 
16211c05dae3SAli Ahmed /**
1622491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1623491d8ee7SSantosh Puranik  *
1624ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1625cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1626cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1627cd9a4666SKonstantin Aladyshev  */
1628ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1629cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1630cd9a4666SKonstantin Aladyshev {
1631c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1632cd9a4666SKonstantin Aladyshev 
1633c21865c4SKonstantin Aladyshev     if (!bootType)
1634cd9a4666SKonstantin Aladyshev     {
1635c21865c4SKonstantin Aladyshev         return;
1636c21865c4SKonstantin Aladyshev     }
1637c21865c4SKonstantin Aladyshev 
1638cd9a4666SKonstantin Aladyshev     // Source target specified
163962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1640cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1641cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1642cd9a4666SKonstantin Aladyshev     {
1643cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1644cd9a4666SKonstantin Aladyshev     }
1645cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1646cd9a4666SKonstantin Aladyshev     {
1647cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1648cd9a4666SKonstantin Aladyshev     }
1649cd9a4666SKonstantin Aladyshev     else
1650cd9a4666SKonstantin Aladyshev     {
165162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
165262598e31SEd Tanous                          "BootSourceOverrideMode: {}",
165362598e31SEd Tanous                          *bootType);
1654ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1655cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1656cd9a4666SKonstantin Aladyshev         return;
1657cd9a4666SKonstantin Aladyshev     }
1658cd9a4666SKonstantin Aladyshev 
1659cd9a4666SKonstantin Aladyshev     // Act on validated parameters
166062598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1661cd9a4666SKonstantin Aladyshev 
16629ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16639ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16649ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
16659ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
1666ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1667cd9a4666SKonstantin Aladyshev         if (ec)
1668cd9a4666SKonstantin Aladyshev         {
1669cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1670cd9a4666SKonstantin Aladyshev             {
1671ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1672cd9a4666SKonstantin Aladyshev                 return;
1673cd9a4666SKonstantin Aladyshev             }
1674b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1675ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1676cd9a4666SKonstantin Aladyshev             return;
1677cd9a4666SKonstantin Aladyshev         }
167862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type update done.");
16799ae226faSGeorge Liu     });
1680cd9a4666SKonstantin Aladyshev }
1681cd9a4666SKonstantin Aladyshev 
1682cd9a4666SKonstantin Aladyshev /**
1683cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1684cd9a4666SKonstantin Aladyshev  *
1685ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1686ac106bf6SEd Tanous  * message.
1687c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1688c21865c4SKonstantin Aladyshev  * @return Integer error code.
1689c21865c4SKonstantin Aladyshev  */
1690ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1691c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1692c21865c4SKonstantin Aladyshev {
1693c21865c4SKonstantin Aladyshev     if (!bootEnable)
1694c21865c4SKonstantin Aladyshev     {
1695c21865c4SKonstantin Aladyshev         return;
1696c21865c4SKonstantin Aladyshev     }
1697c21865c4SKonstantin Aladyshev     // Source target specified
169862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1699c21865c4SKonstantin Aladyshev 
1700c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1701c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1702c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1703c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1704c21865c4SKonstantin Aladyshev     {
1705c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1706c21865c4SKonstantin Aladyshev     }
1707c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1708c21865c4SKonstantin Aladyshev     {
1709c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1710c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1711c21865c4SKonstantin Aladyshev     }
1712c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1713c21865c4SKonstantin Aladyshev     {
1714c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1715c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1716c21865c4SKonstantin Aladyshev     }
1717c21865c4SKonstantin Aladyshev     else
1718c21865c4SKonstantin Aladyshev     {
171962598e31SEd Tanous         BMCWEB_LOG_DEBUG(
172062598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
172162598e31SEd Tanous             *bootEnable);
1722ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1723c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1724c21865c4SKonstantin Aladyshev         return;
1725c21865c4SKonstantin Aladyshev     }
1726c21865c4SKonstantin Aladyshev 
1727c21865c4SKonstantin Aladyshev     // Act on validated parameters
172862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1729c21865c4SKonstantin Aladyshev 
17309ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17319ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17329ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17339ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
1734ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
17358a592810SEd Tanous         if (ec2)
1736c21865c4SKonstantin Aladyshev         {
1737b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
1738ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1739c21865c4SKonstantin Aladyshev             return;
1740c21865c4SKonstantin Aladyshev         }
174162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot override enable update done.");
17429ae226faSGeorge Liu     });
1743c21865c4SKonstantin Aladyshev 
1744c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1745c21865c4SKonstantin Aladyshev     {
1746c21865c4SKonstantin Aladyshev         return;
1747c21865c4SKonstantin Aladyshev     }
1748c21865c4SKonstantin Aladyshev 
1749c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1750c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
175162598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
175262598e31SEd Tanous                      bootOverridePersistent);
1753c21865c4SKonstantin Aladyshev 
17549ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17559ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17569ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot/one_time",
17579ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
1758ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1759c21865c4SKonstantin Aladyshev         if (ec)
1760c21865c4SKonstantin Aladyshev         {
1761b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1762ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1763c21865c4SKonstantin Aladyshev             return;
1764c21865c4SKonstantin Aladyshev         }
176562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot one_time update done.");
17669ae226faSGeorge Liu     });
1767c21865c4SKonstantin Aladyshev }
1768c21865c4SKonstantin Aladyshev 
1769c21865c4SKonstantin Aladyshev /**
1770c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1771c21865c4SKonstantin Aladyshev  *
1772ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1773491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1774491d8ee7SSantosh Puranik  *
1775265c1602SJohnathan Mantey  * @return Integer error code.
1776491d8ee7SSantosh Puranik  */
1777ac106bf6SEd Tanous inline void
1778ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1779cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1780491d8ee7SSantosh Puranik {
1781c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1782c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1783944ffaf9SJohnathan Mantey 
1784c21865c4SKonstantin Aladyshev     if (!bootSource)
1785491d8ee7SSantosh Puranik     {
1786c21865c4SKonstantin Aladyshev         return;
1787c21865c4SKonstantin Aladyshev     }
1788c21865c4SKonstantin Aladyshev 
1789491d8ee7SSantosh Puranik     // Source target specified
179062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1791491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1792ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1793ac106bf6SEd Tanous                              bootModeStr) != 0)
1794491d8ee7SSantosh Puranik     {
179562598e31SEd Tanous         BMCWEB_LOG_DEBUG(
179662598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
179762598e31SEd Tanous             *bootSource);
1798ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1799491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1800491d8ee7SSantosh Puranik         return;
1801491d8ee7SSantosh Puranik     }
1802491d8ee7SSantosh Puranik 
1803944ffaf9SJohnathan Mantey     // Act on validated parameters
180462598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
180562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1806944ffaf9SJohnathan Mantey 
18079ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18089ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18099ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18109ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
1811ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1812491d8ee7SSantosh Puranik         if (ec)
1813491d8ee7SSantosh Puranik         {
1814b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1815ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1816491d8ee7SSantosh Puranik             return;
1817491d8ee7SSantosh Puranik         }
181862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source update done.");
18199ae226faSGeorge Liu     });
1820944ffaf9SJohnathan Mantey 
18219ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18229ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18239ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18249ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
1825ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1826491d8ee7SSantosh Puranik         if (ec)
1827491d8ee7SSantosh Puranik         {
1828b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1829ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1830491d8ee7SSantosh Puranik             return;
1831491d8ee7SSantosh Puranik         }
183262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode update done.");
18339ae226faSGeorge Liu     });
1834cd9a4666SKonstantin Aladyshev }
1835944ffaf9SJohnathan Mantey 
1836cd9a4666SKonstantin Aladyshev /**
1837c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1838491d8ee7SSantosh Puranik  *
1839ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1840491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1841cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1842491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1843491d8ee7SSantosh Puranik  *
1844265c1602SJohnathan Mantey  * @return Integer error code.
1845491d8ee7SSantosh Puranik  */
1846c21865c4SKonstantin Aladyshev 
1847ac106bf6SEd Tanous inline void
1848ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1849c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1850c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1851c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1852491d8ee7SSantosh Puranik {
185362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1854491d8ee7SSantosh Puranik 
1855ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1856ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1857ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1858491d8ee7SSantosh Puranik }
1859491d8ee7SSantosh Puranik 
1860c6a620f2SGeorge Liu /**
186198e386ecSGunnar Mills  * @brief Sets AssetTag
186298e386ecSGunnar Mills  *
1863ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
186498e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
186598e386ecSGunnar Mills  *
186698e386ecSGunnar Mills  * @return None.
186798e386ecSGunnar Mills  */
1868ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
186998e386ecSGunnar Mills                         const std::string& assetTag)
187098e386ecSGunnar Mills {
1871e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1872e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1873e99073f5SGeorge Liu     dbus::utility::getSubTree(
1874e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1875ac106bf6SEd Tanous         [asyncResp,
1876e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1877b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
187898e386ecSGunnar Mills         if (ec)
187998e386ecSGunnar Mills         {
188062598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1881ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188298e386ecSGunnar Mills             return;
188398e386ecSGunnar Mills         }
188426f6976fSEd Tanous         if (subtree.empty())
188598e386ecSGunnar Mills         {
188662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1887ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188898e386ecSGunnar Mills             return;
188998e386ecSGunnar Mills         }
189098e386ecSGunnar Mills         // Assume only 1 system D-Bus object
189198e386ecSGunnar Mills         // Throw an error if there is more than 1
189298e386ecSGunnar Mills         if (subtree.size() > 1)
189398e386ecSGunnar Mills         {
189462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1895ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189698e386ecSGunnar Mills             return;
189798e386ecSGunnar Mills         }
189898e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
189998e386ecSGunnar Mills         {
190062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1901ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
190298e386ecSGunnar Mills             return;
190398e386ecSGunnar Mills         }
190498e386ecSGunnar Mills 
190598e386ecSGunnar Mills         const std::string& path = subtree[0].first;
190698e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
190798e386ecSGunnar Mills 
190898e386ecSGunnar Mills         if (service.empty())
190998e386ecSGunnar Mills         {
191062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1911ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
191298e386ecSGunnar Mills             return;
191398e386ecSGunnar Mills         }
191498e386ecSGunnar Mills 
19159ae226faSGeorge Liu         sdbusplus::asio::setProperty(
19169ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
19179ae226faSGeorge Liu             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
19189ae226faSGeorge Liu             assetTag, [asyncResp](const boost::system::error_code& ec2) {
191998e386ecSGunnar Mills             if (ec2)
192098e386ecSGunnar Mills             {
1921b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
192262598e31SEd Tanous                                  ec2);
1923ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
192498e386ecSGunnar Mills                 return;
192598e386ecSGunnar Mills             }
19269ae226faSGeorge Liu         });
1927e99073f5SGeorge Liu     });
192898e386ecSGunnar Mills }
192998e386ecSGunnar Mills 
193098e386ecSGunnar Mills /**
19319dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
19329dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
19339dcfe8c1SAlbert Zhang  *
19349dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
19359dcfe8c1SAlbert Zhang  * stopBootOnFault
19369dcfe8c1SAlbert Zhang  *
19379dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
19389dcfe8c1SAlbert Zhang  */
19399dcfe8c1SAlbert Zhang inline std::optional<bool>
19409dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
19419dcfe8c1SAlbert Zhang {
19429dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
19439dcfe8c1SAlbert Zhang     {
19449dcfe8c1SAlbert Zhang         return true;
19459dcfe8c1SAlbert Zhang     }
19469dcfe8c1SAlbert Zhang 
19479dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
19489dcfe8c1SAlbert Zhang     {
19499dcfe8c1SAlbert Zhang         return false;
19509dcfe8c1SAlbert Zhang     }
19519dcfe8c1SAlbert Zhang 
19529dcfe8c1SAlbert Zhang     return std::nullopt;
19539dcfe8c1SAlbert Zhang }
19549dcfe8c1SAlbert Zhang 
19559dcfe8c1SAlbert Zhang /**
19569dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
19579dcfe8c1SAlbert Zhang  *
1958fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
19599dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
19609dcfe8c1SAlbert Zhang  *
19619dcfe8c1SAlbert Zhang  * @return None.
19629dcfe8c1SAlbert Zhang  */
1963fc3edfddSEd Tanous inline void
1964fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19659dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
19669dcfe8c1SAlbert Zhang {
196762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
19689dcfe8c1SAlbert Zhang 
19699dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
19709dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
19719dcfe8c1SAlbert Zhang     {
197262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
197362598e31SEd Tanous                          stopBootOnFault);
1974fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
19759dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
19769dcfe8c1SAlbert Zhang         return;
19779dcfe8c1SAlbert Zhang     }
19789dcfe8c1SAlbert Zhang 
1979fc3edfddSEd Tanous     sdbusplus::asio::setProperty(
1980fc3edfddSEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
19819dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
1982fc3edfddSEd Tanous         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1983fc3edfddSEd Tanous         *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
19849dcfe8c1SAlbert Zhang         if (ec)
19859dcfe8c1SAlbert Zhang         {
19869dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
19879dcfe8c1SAlbert Zhang             {
1988b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1989fc3edfddSEd Tanous                 messages::internalError(asyncResp->res);
19909dcfe8c1SAlbert Zhang             }
19919dcfe8c1SAlbert Zhang             return;
19929dcfe8c1SAlbert Zhang         }
19939dcfe8c1SAlbert Zhang     });
19949dcfe8c1SAlbert Zhang }
19959dcfe8c1SAlbert Zhang 
19969dcfe8c1SAlbert Zhang /**
199769f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
199869f35306SGunnar Mills  *
1999ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
200069f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
200169f35306SGunnar Mills  *
200269f35306SGunnar Mills  * @return None.
200369f35306SGunnar Mills  */
2004ac106bf6SEd Tanous inline void
2005ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2006f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
200769f35306SGunnar Mills {
200862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
200969f35306SGunnar Mills 
201069f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
2011543f4400SEd Tanous     bool autoRebootEnabled = false;
201269f35306SGunnar Mills 
201369f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
201469f35306SGunnar Mills     {
201569f35306SGunnar Mills         autoRebootEnabled = false;
201669f35306SGunnar Mills     }
201769f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
201869f35306SGunnar Mills     {
201969f35306SGunnar Mills         autoRebootEnabled = true;
202069f35306SGunnar Mills     }
202169f35306SGunnar Mills     else
202269f35306SGunnar Mills     {
202362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
202462598e31SEd Tanous                          automaticRetryConfig);
2025ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
202669f35306SGunnar Mills                                          "AutomaticRetryConfig");
202769f35306SGunnar Mills         return;
202869f35306SGunnar Mills     }
202969f35306SGunnar Mills 
20309ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20319ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20329ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/auto_reboot",
20339ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
20349ae226faSGeorge Liu         autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
203569f35306SGunnar Mills         if (ec)
203669f35306SGunnar Mills         {
2037b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2038ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
203969f35306SGunnar Mills             return;
204069f35306SGunnar Mills         }
20419ae226faSGeorge Liu     });
204269f35306SGunnar Mills }
204369f35306SGunnar Mills 
20448d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
20458d69c668SEd Tanous {
20468d69c668SEd Tanous     if (policy == "AlwaysOn")
20478d69c668SEd Tanous     {
20488d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
20498d69c668SEd Tanous     }
20508d69c668SEd Tanous     if (policy == "AlwaysOff")
20518d69c668SEd Tanous     {
20528d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
20538d69c668SEd Tanous     }
20548d69c668SEd Tanous     if (policy == "LastState")
20558d69c668SEd Tanous     {
20568d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
20578d69c668SEd Tanous     }
20588d69c668SEd Tanous     return "";
20598d69c668SEd Tanous }
20608d69c668SEd Tanous 
206169f35306SGunnar Mills /**
2062c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
2063c6a620f2SGeorge Liu  *
2064ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2065c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
2066c6a620f2SGeorge Liu  *
2067c6a620f2SGeorge Liu  * @return None.
2068c6a620f2SGeorge Liu  */
20698d1b46d7Szhanghch05 inline void
2070ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20718d69c668SEd Tanous                           std::string_view policy)
2072c6a620f2SGeorge Liu {
207362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
2074c6a620f2SGeorge Liu 
20758d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2076c6a620f2SGeorge Liu 
20778d69c668SEd Tanous     if (powerRestorePolicy.empty())
2078c6a620f2SGeorge Liu     {
2079ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20804e69c904SGunnar Mills                                          "PowerRestorePolicy");
2081c6a620f2SGeorge Liu         return;
2082c6a620f2SGeorge Liu     }
2083c6a620f2SGeorge Liu 
20849ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20859ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20869ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
20879ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
20889ae226faSGeorge Liu         powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2089c6a620f2SGeorge Liu         if (ec)
2090c6a620f2SGeorge Liu         {
2091b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2092ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2093c6a620f2SGeorge Liu             return;
2094c6a620f2SGeorge Liu         }
20959ae226faSGeorge Liu     });
2096c6a620f2SGeorge Liu }
2097c6a620f2SGeorge Liu 
2098a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2099a6349918SAppaRao Puli /**
2100a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2101a6349918SAppaRao Puli  *
2102ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
2103a6349918SAppaRao Puli  *
2104a6349918SAppaRao Puli  * @return None.
2105a6349918SAppaRao Puli  */
2106ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
2107a6349918SAppaRao Puli {
210862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
2109bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2110bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2111bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
2112ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2113b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2114b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2115ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2116ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
211750626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
211850626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
211950626f4fSJames Feist 
2120a6349918SAppaRao Puli         if (ec)
2121a6349918SAppaRao Puli         {
212262598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2123b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2124b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2125a6349918SAppaRao Puli             return;
2126a6349918SAppaRao Puli         }
2127a6349918SAppaRao Puli 
2128a6349918SAppaRao Puli         const bool* provState = nullptr;
2129a6349918SAppaRao Puli         const bool* lockState = nullptr;
2130bc1d29deSKrzysztof Grobelny 
2131bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
21320d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
21330d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2134bc1d29deSKrzysztof Grobelny 
2135bc1d29deSKrzysztof Grobelny         if (!success)
2136a6349918SAppaRao Puli         {
2137ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2138bc1d29deSKrzysztof Grobelny             return;
2139a6349918SAppaRao Puli         }
2140a6349918SAppaRao Puli 
2141a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2142a6349918SAppaRao Puli         {
214362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2144ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2145a6349918SAppaRao Puli             return;
2146a6349918SAppaRao Puli         }
2147a6349918SAppaRao Puli 
2148a6349918SAppaRao Puli         if (*provState == true)
2149a6349918SAppaRao Puli         {
2150a6349918SAppaRao Puli             if (*lockState == true)
2151a6349918SAppaRao Puli             {
2152a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2153a6349918SAppaRao Puli             }
2154a6349918SAppaRao Puli             else
2155a6349918SAppaRao Puli             {
2156a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2157a6349918SAppaRao Puli             }
2158a6349918SAppaRao Puli         }
2159a6349918SAppaRao Puli         else
2160a6349918SAppaRao Puli         {
2161a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2162a6349918SAppaRao Puli         }
2163bc1d29deSKrzysztof Grobelny     });
2164a6349918SAppaRao Puli }
2165a6349918SAppaRao Puli #endif
2166a6349918SAppaRao Puli 
2167491d8ee7SSantosh Puranik /**
21683a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
21693a2d0424SChris Cain  *
2170ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21713a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
21723a2d0424SChris Cain  *
21733a2d0424SChris Cain  * @return None.
21743a2d0424SChris Cain  */
2175ac106bf6SEd Tanous inline void
2176ac106bf6SEd Tanous     translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21773a2d0424SChris Cain                        const std::string& modeValue)
21783a2d0424SChris Cain {
21790fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21803a2d0424SChris Cain     {
2181ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "Static";
21823a2d0424SChris Cain     }
21830fda0f12SGeorge Liu     else if (
21840fda0f12SGeorge Liu         modeValue ==
21850fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21863a2d0424SChris Cain     {
2187ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
21883a2d0424SChris Cain     }
21890fda0f12SGeorge Liu     else if (modeValue ==
21900fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21913a2d0424SChris Cain     {
2192ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
21933a2d0424SChris Cain     }
21940fda0f12SGeorge Liu     else if (modeValue ==
21950fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
21963a2d0424SChris Cain     {
2197ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "OEM";
21983a2d0424SChris Cain     }
21993a2d0424SChris Cain     else
22003a2d0424SChris Cain     {
22013a2d0424SChris Cain         // Any other values would be invalid
220262598e31SEd Tanous         BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue);
2203ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
22043a2d0424SChris Cain     }
22053a2d0424SChris Cain }
22063a2d0424SChris Cain 
22073a2d0424SChris Cain /**
22083a2d0424SChris Cain  * @brief Retrieves system power mode
22093a2d0424SChris Cain  *
2210ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22113a2d0424SChris Cain  *
22123a2d0424SChris Cain  * @return None.
22133a2d0424SChris Cain  */
2214ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22153a2d0424SChris Cain {
221662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
22173a2d0424SChris Cain 
22183a2d0424SChris Cain     // Get Power Mode object path:
2219e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2220e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2221e99073f5SGeorge Liu     dbus::utility::getSubTree(
2222e99073f5SGeorge Liu         "/", 0, interfaces,
2223ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2224b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22253a2d0424SChris Cain         if (ec)
22263a2d0424SChris Cain         {
222762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
222862598e31SEd Tanous                              ec);
22293a2d0424SChris Cain             // This is an optional D-Bus object so just return if
22303a2d0424SChris Cain             // error occurs
22313a2d0424SChris Cain             return;
22323a2d0424SChris Cain         }
22333a2d0424SChris Cain         if (subtree.empty())
22343a2d0424SChris Cain         {
22353a2d0424SChris Cain             // As noted above, this is an optional interface so just return
22363a2d0424SChris Cain             // if there is no instance found
22373a2d0424SChris Cain             return;
22383a2d0424SChris Cain         }
22393a2d0424SChris Cain         if (subtree.size() > 1)
22403a2d0424SChris Cain         {
22413a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22423a2d0424SChris Cain             // error
224362598e31SEd Tanous             BMCWEB_LOG_DEBUG(
224462598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
224562598e31SEd Tanous                 subtree.size());
2246ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22473a2d0424SChris Cain             return;
22483a2d0424SChris Cain         }
22493a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22503a2d0424SChris Cain         {
225162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2252ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22533a2d0424SChris Cain             return;
22543a2d0424SChris Cain         }
22553a2d0424SChris Cain         const std::string& path = subtree[0].first;
22563a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22573a2d0424SChris Cain         if (service.empty())
22583a2d0424SChris Cain         {
225962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2260ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22613a2d0424SChris Cain             return;
22623a2d0424SChris Cain         }
22633a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
22641e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
22651e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
22661e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2267ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
22681e1e598dSJonathan Doman                         const std::string& pmode) {
22698a592810SEd Tanous             if (ec2)
22703a2d0424SChris Cain             {
2271b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error on PowerMode Get: {}",
227262598e31SEd Tanous                                  ec2);
2273ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22743a2d0424SChris Cain                 return;
22753a2d0424SChris Cain             }
22763a2d0424SChris Cain 
2277ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2278002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
22793a2d0424SChris Cain 
228062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Current power mode: {}", pmode);
2281ac106bf6SEd Tanous             translatePowerMode(asyncResp, pmode);
22821e1e598dSJonathan Doman         });
2283e99073f5SGeorge Liu     });
22843a2d0424SChris Cain }
22853a2d0424SChris Cain 
22863a2d0424SChris Cain /**
22873a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22883a2d0424SChris Cain  * name associated with that string
22893a2d0424SChris Cain  *
2290ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22913a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
22923a2d0424SChris Cain  *
22933a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22943a2d0424SChris Cain  */
22953a2d0424SChris Cain inline std::string
2296ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22973a2d0424SChris Cain                       const std::string& modeString)
22983a2d0424SChris Cain {
22993a2d0424SChris Cain     std::string mode;
23003a2d0424SChris Cain 
23013a2d0424SChris Cain     if (modeString == "Static")
23023a2d0424SChris Cain     {
23033a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
23043a2d0424SChris Cain     }
23053a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
23063a2d0424SChris Cain     {
23070fda0f12SGeorge Liu         mode =
23080fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
23093a2d0424SChris Cain     }
23103a2d0424SChris Cain     else if (modeString == "PowerSaving")
23113a2d0424SChris Cain     {
23123a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
23133a2d0424SChris Cain     }
23143a2d0424SChris Cain     else
23153a2d0424SChris Cain     {
2316ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, modeString,
2317ac106bf6SEd Tanous                                          "PowerMode");
23183a2d0424SChris Cain     }
23193a2d0424SChris Cain     return mode;
23203a2d0424SChris Cain }
23213a2d0424SChris Cain 
23223a2d0424SChris Cain /**
23233a2d0424SChris Cain  * @brief Sets system power mode.
23243a2d0424SChris Cain  *
2325ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
23263a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
23273a2d0424SChris Cain  *
23283a2d0424SChris Cain  * @return None.
23293a2d0424SChris Cain  */
2330ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23313a2d0424SChris Cain                          const std::string& pmode)
23323a2d0424SChris Cain {
233362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
23343a2d0424SChris Cain 
2335ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
23363a2d0424SChris Cain     if (powerMode.empty())
23373a2d0424SChris Cain     {
23383a2d0424SChris Cain         return;
23393a2d0424SChris Cain     }
23403a2d0424SChris Cain 
23413a2d0424SChris Cain     // Get Power Mode object path:
2342e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2343e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2344e99073f5SGeorge Liu     dbus::utility::getSubTree(
2345e99073f5SGeorge Liu         "/", 0, interfaces,
2346ac106bf6SEd Tanous         [asyncResp,
2347e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2348b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23493a2d0424SChris Cain         if (ec)
23503a2d0424SChris Cain         {
2351b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
235262598e31SEd Tanous                              ec);
23533a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2354ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23553a2d0424SChris Cain             return;
23563a2d0424SChris Cain         }
23573a2d0424SChris Cain         if (subtree.empty())
23583a2d0424SChris Cain         {
23593a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2360ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23613a2d0424SChris Cain                                        "PowerMode");
23623a2d0424SChris Cain             return;
23633a2d0424SChris Cain         }
23643a2d0424SChris Cain         if (subtree.size() > 1)
23653a2d0424SChris Cain         {
23663a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
23673a2d0424SChris Cain             // error
236862598e31SEd Tanous             BMCWEB_LOG_DEBUG(
236962598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
237062598e31SEd Tanous                 subtree.size());
2371ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23723a2d0424SChris Cain             return;
23733a2d0424SChris Cain         }
23743a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23753a2d0424SChris Cain         {
237662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2377ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23783a2d0424SChris Cain             return;
23793a2d0424SChris Cain         }
23803a2d0424SChris Cain         const std::string& path = subtree[0].first;
23813a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
23823a2d0424SChris Cain         if (service.empty())
23833a2d0424SChris Cain         {
238462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2385ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23863a2d0424SChris Cain             return;
23873a2d0424SChris Cain         }
23883a2d0424SChris Cain 
238962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23903a2d0424SChris Cain 
23913a2d0424SChris Cain         // Set the Power Mode property
23929ae226faSGeorge Liu         sdbusplus::asio::setProperty(
23939ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
23949ae226faSGeorge Liu             "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
2395ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
23968a592810SEd Tanous             if (ec2)
23973a2d0424SChris Cain             {
2398b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2399ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24003a2d0424SChris Cain                 return;
24013a2d0424SChris Cain             }
24029ae226faSGeorge Liu         });
2403e99073f5SGeorge Liu     });
24043a2d0424SChris Cain }
24053a2d0424SChris Cain 
24063a2d0424SChris Cain /**
240751709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
240851709ffdSYong Li  *
240951709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
241051709ffdSYong Li  *
241151709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
241251709ffdSYong Li  * translation cannot be done, returns an empty string.
241351709ffdSYong Li  */
241423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
241551709ffdSYong Li {
241651709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
241751709ffdSYong Li     {
241851709ffdSYong Li         return "None";
241951709ffdSYong Li     }
24203174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
242151709ffdSYong Li     {
242251709ffdSYong Li         return "ResetSystem";
242351709ffdSYong Li     }
24243174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
242551709ffdSYong Li     {
242651709ffdSYong Li         return "PowerDown";
242751709ffdSYong Li     }
24283174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
242951709ffdSYong Li     {
243051709ffdSYong Li         return "PowerCycle";
243151709ffdSYong Li     }
243251709ffdSYong Li 
243351709ffdSYong Li     return "";
243451709ffdSYong Li }
243551709ffdSYong Li 
243651709ffdSYong Li /**
2437c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2438c45f0082SYong Li  *
2439c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2440c45f0082SYong Li  *
2441c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2442c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2443c45f0082SYong Li  */
2444c45f0082SYong Li 
244523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2446c45f0082SYong Li {
2447c45f0082SYong Li     if (rfAction == "None")
2448c45f0082SYong Li     {
2449c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2450c45f0082SYong Li     }
24513174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2452c45f0082SYong Li     {
2453c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2454c45f0082SYong Li     }
24553174e4dfSEd Tanous     if (rfAction == "PowerDown")
2456c45f0082SYong Li     {
2457c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2458c45f0082SYong Li     }
24593174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2460c45f0082SYong Li     {
2461c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2462c45f0082SYong Li     }
2463c45f0082SYong Li 
2464c45f0082SYong Li     return "";
2465c45f0082SYong Li }
2466c45f0082SYong Li 
2467c45f0082SYong Li /**
246851709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
246951709ffdSYong Li  *
2470ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
247151709ffdSYong Li  *
247251709ffdSYong Li  * @return None.
247351709ffdSYong Li  */
24748d1b46d7Szhanghch05 inline void
2475ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
247651709ffdSYong Li {
247762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2478bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2479bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2480bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2481bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2482ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2483b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
248451709ffdSYong Li         if (ec)
248551709ffdSYong Li         {
248651709ffdSYong Li             // watchdog service is stopped
248762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
248851709ffdSYong Li             return;
248951709ffdSYong Li         }
249051709ffdSYong Li 
249162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
249251709ffdSYong Li 
249351709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2494ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
249551709ffdSYong Li 
249651709ffdSYong Li         // watchdog service is running/enabled
249751709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
249851709ffdSYong Li 
2499bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2500bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
250151709ffdSYong Li 
2502bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2503bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2504bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2505bc1d29deSKrzysztof Grobelny 
2506bc1d29deSKrzysztof Grobelny         if (!success)
250751709ffdSYong Li         {
2508ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2509601af5edSChicago Duan             return;
251051709ffdSYong Li         }
251151709ffdSYong Li 
2512bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
251351709ffdSYong Li         {
2514bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
251551709ffdSYong Li         }
251651709ffdSYong Li 
2517bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2518bc1d29deSKrzysztof Grobelny         {
2519bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
252051709ffdSYong Li             if (action.empty())
252151709ffdSYong Li             {
2522ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2523601af5edSChicago Duan                 return;
252451709ffdSYong Li             }
252551709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
252651709ffdSYong Li         }
2527bc1d29deSKrzysztof Grobelny     });
252851709ffdSYong Li }
252951709ffdSYong Li 
253051709ffdSYong Li /**
2531c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2532c45f0082SYong Li  *
2533ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2534c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2535c45f0082SYong Li  *                       RF request.
2536c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2537c45f0082SYong Li  *
2538c45f0082SYong Li  * @return None.
2539c45f0082SYong Li  */
2540ac106bf6SEd Tanous inline void
2541ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2542c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2543c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2544c45f0082SYong Li {
254562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2546c45f0082SYong Li 
2547c45f0082SYong Li     if (wdtTimeOutAction)
2548c45f0082SYong Li     {
2549c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2550c45f0082SYong Li         // check if TimeOut Action is Valid
2551c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2552c45f0082SYong Li         {
255362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
255462598e31SEd Tanous                              *wdtTimeOutAction);
2555ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2556c45f0082SYong Li                                              "TimeoutAction");
2557c45f0082SYong Li             return;
2558c45f0082SYong Li         }
2559c45f0082SYong Li 
25609ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25619ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25629ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25639ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
25649ae226faSGeorge Liu             wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2565c45f0082SYong Li             if (ec)
2566c45f0082SYong Li             {
2567b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2568ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2569c45f0082SYong Li                 return;
2570c45f0082SYong Li             }
25719ae226faSGeorge Liu         });
2572c45f0082SYong Li     }
2573c45f0082SYong Li 
2574c45f0082SYong Li     if (wdtEnable)
2575c45f0082SYong Li     {
25769ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25779ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25789ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25799ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
2580ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2581c45f0082SYong Li             if (ec)
2582c45f0082SYong Li             {
2583b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2584ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2585c45f0082SYong Li                 return;
2586c45f0082SYong Li             }
25879ae226faSGeorge Liu         });
2588c45f0082SYong Li     }
2589c45f0082SYong Li }
2590c45f0082SYong Li 
259137bbf98cSChris Cain /**
259237bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
259337bbf98cSChris Cain  *
2594ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
259537bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
259637bbf98cSChris Cain  *
259737bbf98cSChris Cain  * @return true if successful
259837bbf98cSChris Cain  */
25991e5b7c88SJiaqing Zhao inline bool
2600ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26011e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
260237bbf98cSChris Cain {
2603bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2604bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2605bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2606bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2607bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2608bc1d29deSKrzysztof Grobelny 
2609bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2610bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26112661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26122661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26132661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2614bc1d29deSKrzysztof Grobelny 
2615bc1d29deSKrzysztof Grobelny     if (!success)
261637bbf98cSChris Cain     {
261737bbf98cSChris Cain         return false;
261837bbf98cSChris Cain     }
2619bc1d29deSKrzysztof Grobelny 
2620bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
262137bbf98cSChris Cain     {
2622ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
262337bbf98cSChris Cain     }
2624bc1d29deSKrzysztof Grobelny 
2625bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
262637bbf98cSChris Cain     {
2627ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2628bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
262937bbf98cSChris Cain     }
2630bc1d29deSKrzysztof Grobelny 
2631bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2632bc1d29deSKrzysztof Grobelny     {
2633bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2634ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
263537bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
263637bbf98cSChris Cain                 .count();
263737bbf98cSChris Cain     }
2638bc1d29deSKrzysztof Grobelny 
2639bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
264037bbf98cSChris Cain     {
2641ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2642bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
264337bbf98cSChris Cain     }
2644bc1d29deSKrzysztof Grobelny 
2645bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
264637bbf98cSChris Cain     {
2647bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2648ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
264937bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
265037bbf98cSChris Cain                 .count();
265137bbf98cSChris Cain     }
265237bbf98cSChris Cain 
265337bbf98cSChris Cain     return true;
265437bbf98cSChris Cain }
265537bbf98cSChris Cain 
265637bbf98cSChris Cain /**
265737bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
265837bbf98cSChris Cain  *
2659ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
266037bbf98cSChris Cain  *
266137bbf98cSChris Cain  * @return None.
266237bbf98cSChris Cain  */
2663ac106bf6SEd Tanous inline void
2664ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
266537bbf98cSChris Cain {
266662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
266737bbf98cSChris Cain 
266837bbf98cSChris Cain     // Get IdlePowerSaver object path:
2669e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2670e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2671e99073f5SGeorge Liu     dbus::utility::getSubTree(
2672e99073f5SGeorge Liu         "/", 0, interfaces,
2673ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2674b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
267537bbf98cSChris Cain         if (ec)
267637bbf98cSChris Cain         {
2677b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
267862598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
267962598e31SEd Tanous                 ec);
2680ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
268137bbf98cSChris Cain             return;
268237bbf98cSChris Cain         }
268337bbf98cSChris Cain         if (subtree.empty())
268437bbf98cSChris Cain         {
268537bbf98cSChris Cain             // This is an optional interface so just return
268637bbf98cSChris Cain             // if there is no instance found
268762598e31SEd Tanous             BMCWEB_LOG_DEBUG("No instances found");
268837bbf98cSChris Cain             return;
268937bbf98cSChris Cain         }
269037bbf98cSChris Cain         if (subtree.size() > 1)
269137bbf98cSChris Cain         {
269237bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
269337bbf98cSChris Cain             // is an error
269462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
269562598e31SEd Tanous                              "Power.IdlePowerSaver objects: {}",
269662598e31SEd Tanous                              subtree.size());
2697ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269837bbf98cSChris Cain             return;
269937bbf98cSChris Cain         }
270037bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
270137bbf98cSChris Cain         {
270262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2703ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
270437bbf98cSChris Cain             return;
270537bbf98cSChris Cain         }
270637bbf98cSChris Cain         const std::string& path = subtree[0].first;
270737bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
270837bbf98cSChris Cain         if (service.empty())
270937bbf98cSChris Cain         {
271062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2711ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
271237bbf98cSChris Cain             return;
271337bbf98cSChris Cain         }
271437bbf98cSChris Cain 
271537bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2716bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2717bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2718bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2719ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27201e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
27218a592810SEd Tanous             if (ec2)
272237bbf98cSChris Cain             {
272362598e31SEd Tanous                 BMCWEB_LOG_ERROR(
272462598e31SEd Tanous                     "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
2725ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272637bbf98cSChris Cain                 return;
272737bbf98cSChris Cain             }
272837bbf98cSChris Cain 
2729ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
273037bbf98cSChris Cain             {
2731ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
273237bbf98cSChris Cain                 return;
273337bbf98cSChris Cain             }
2734bc1d29deSKrzysztof Grobelny         });
2735e99073f5SGeorge Liu     });
273637bbf98cSChris Cain 
273762598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
273837bbf98cSChris Cain }
273937bbf98cSChris Cain 
274037bbf98cSChris Cain /**
274137bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
274237bbf98cSChris Cain  *
2743ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
274437bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
274537bbf98cSChris Cain  *                       RF request.
274637bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
274737bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
274837bbf98cSChris Cain  * before entering idle state.
274937bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
275037bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
275137bbf98cSChris Cain  * before exiting idle state
275237bbf98cSChris Cain  *
275337bbf98cSChris Cain  * @return None.
275437bbf98cSChris Cain  */
2755ac106bf6SEd Tanous inline void
2756ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
275737bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
275837bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
275937bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
276037bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
276137bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
276237bbf98cSChris Cain {
276362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
276437bbf98cSChris Cain 
276537bbf98cSChris Cain     // Get IdlePowerSaver object path:
2766e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2767e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2768e99073f5SGeorge Liu     dbus::utility::getSubTree(
2769e99073f5SGeorge Liu         "/", 0, interfaces,
2770ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2771e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2772b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
277337bbf98cSChris Cain         if (ec)
277437bbf98cSChris Cain         {
2775b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
277662598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
277762598e31SEd Tanous                 ec);
2778ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
277937bbf98cSChris Cain             return;
278037bbf98cSChris Cain         }
278137bbf98cSChris Cain         if (subtree.empty())
278237bbf98cSChris Cain         {
278337bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2784ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
278537bbf98cSChris Cain                                        "IdlePowerSaver");
278637bbf98cSChris Cain             return;
278737bbf98cSChris Cain         }
278837bbf98cSChris Cain         if (subtree.size() > 1)
278937bbf98cSChris Cain         {
279037bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
279137bbf98cSChris Cain             // is an error
279262598e31SEd Tanous             BMCWEB_LOG_DEBUG(
279362598e31SEd Tanous                 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
279462598e31SEd Tanous                 subtree.size());
2795ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
279637bbf98cSChris Cain             return;
279737bbf98cSChris Cain         }
279837bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
279937bbf98cSChris Cain         {
280062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2801ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
280237bbf98cSChris Cain             return;
280337bbf98cSChris Cain         }
280437bbf98cSChris Cain         const std::string& path = subtree[0].first;
280537bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
280637bbf98cSChris Cain         if (service.empty())
280737bbf98cSChris Cain         {
280862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2809ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
281037bbf98cSChris Cain             return;
281137bbf98cSChris Cain         }
281237bbf98cSChris Cain 
281337bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
281437bbf98cSChris Cain         // need to be updated
281537bbf98cSChris Cain 
281637bbf98cSChris Cain         if (ipsEnable)
281737bbf98cSChris Cain         {
28189ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28199ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28209ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
28219ae226faSGeorge Liu                 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
28228a592810SEd Tanous                 if (ec2)
282337bbf98cSChris Cain                 {
2824b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2825ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
282637bbf98cSChris Cain                     return;
282737bbf98cSChris Cain                 }
28289ae226faSGeorge Liu             });
282937bbf98cSChris Cain         }
283037bbf98cSChris Cain         if (ipsEnterUtil)
283137bbf98cSChris Cain         {
28329ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28339ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28349ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28359ae226faSGeorge Liu                 "EnterUtilizationPercent", *ipsEnterUtil,
2836ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28378a592810SEd Tanous                 if (ec2)
283837bbf98cSChris Cain                 {
2839b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2840ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
284137bbf98cSChris Cain                     return;
284237bbf98cSChris Cain                 }
28439ae226faSGeorge Liu             });
284437bbf98cSChris Cain         }
284537bbf98cSChris Cain         if (ipsEnterTime)
284637bbf98cSChris Cain         {
284737bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
284837bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
28499ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28509ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28519ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28529ae226faSGeorge Liu                 "EnterDwellTime", timeMilliseconds,
2853ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28548a592810SEd Tanous                 if (ec2)
285537bbf98cSChris Cain                 {
2856b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2857ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
285837bbf98cSChris Cain                     return;
285937bbf98cSChris Cain                 }
28609ae226faSGeorge Liu             });
286137bbf98cSChris Cain         }
286237bbf98cSChris Cain         if (ipsExitUtil)
286337bbf98cSChris Cain         {
28649ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28659ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28669ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28679ae226faSGeorge Liu                 "ExitUtilizationPercent", *ipsExitUtil,
2868ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28698a592810SEd Tanous                 if (ec2)
287037bbf98cSChris Cain                 {
2871b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2872ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
287337bbf98cSChris Cain                     return;
287437bbf98cSChris Cain                 }
28759ae226faSGeorge Liu             });
287637bbf98cSChris Cain         }
287737bbf98cSChris Cain         if (ipsExitTime)
287837bbf98cSChris Cain         {
287937bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
288037bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
28819ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28829ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28839ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28849ae226faSGeorge Liu                 "ExitDwellTime", timeMilliseconds,
2885ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28868a592810SEd Tanous                 if (ec2)
288737bbf98cSChris Cain                 {
2888b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2889ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
289037bbf98cSChris Cain                     return;
289137bbf98cSChris Cain                 }
28929ae226faSGeorge Liu             });
289337bbf98cSChris Cain         }
2894e99073f5SGeorge Liu     });
289537bbf98cSChris Cain 
289662598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
289737bbf98cSChris Cain }
289837bbf98cSChris Cain 
2899c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2900dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2901dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2902dd60b9edSEd Tanous {
2903dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2904dd60b9edSEd Tanous     {
2905dd60b9edSEd Tanous         return;
2906dd60b9edSEd Tanous     }
2907dd60b9edSEd Tanous     asyncResp->res.addHeader(
2908dd60b9edSEd Tanous         boost::beast::http::field::link,
2909dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2910dd60b9edSEd Tanous }
2911dd60b9edSEd Tanous 
2912c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2913c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2914c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29151abe55efSEd Tanous {
29163ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2917f4c99e70SEd Tanous     {
2918f4c99e70SEd Tanous         return;
2919f4c99e70SEd Tanous     }
2920dd60b9edSEd Tanous 
2921dd60b9edSEd Tanous     asyncResp->res.addHeader(
2922dd60b9edSEd Tanous         boost::beast::http::field::link,
2923dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
29248d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
29250f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
29268d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
29278d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2928462023adSSunitha Harish 
29297f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
29307f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
29317f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
29327f3e84a1SEd Tanous     {
29337f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
29347f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29357f3e84a1SEd Tanous         return;
29367f3e84a1SEd Tanous     }
29377f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
29387f3e84a1SEd Tanous     nlohmann::json::object_t system;
29397f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
29407f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
29411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2942002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
29431e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2944002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
29455e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
29461e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
29477f3e84a1SEd Tanous         if (ec2)
2948462023adSSunitha Harish         {
29497f3e84a1SEd Tanous             return;
29507f3e84a1SEd Tanous         }
29517f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
29527f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
29537f3e84a1SEd Tanous         {
295462598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
29557f3e84a1SEd Tanous             return;
29567f3e84a1SEd Tanous         }
29577f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
29587f3e84a1SEd Tanous         if (count == nullptr)
29597f3e84a1SEd Tanous         {
296062598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
29617f3e84a1SEd Tanous             return;
29627f3e84a1SEd Tanous         }
29637f3e84a1SEd Tanous         *count = *count + 1;
296462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
29657f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
29661476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2967002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
29687f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
29691e1e598dSJonathan Doman     });
2970c1e219d5SEd Tanous }
2971c1e219d5SEd Tanous 
2972c1e219d5SEd Tanous /**
29737e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
29747e860f15SJohn Edward Broadbent  */
29754f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29767e860f15SJohn Edward Broadbent {
297789492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
297889492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
297989492a15SPatrick Williams     constexpr const char* interfaceName =
29807e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
298189492a15SPatrick Williams     constexpr const char* method = "NMI";
29827e860f15SJohn Edward Broadbent 
29837e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
29845e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
29857e860f15SJohn Edward Broadbent         if (ec)
29867e860f15SJohn Edward Broadbent         {
298762598e31SEd Tanous             BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
29887e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
29897e860f15SJohn Edward Broadbent             return;
29907e860f15SJohn Edward Broadbent         }
29917e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
29927e860f15SJohn Edward Broadbent     },
29937e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
29947e860f15SJohn Edward Broadbent }
2995c5b2abe0SLewanczyk, Dawid 
2996c5b2abe0SLewanczyk, Dawid /**
2997fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
2998fc903b3dSAndrew Geissler  */
2999fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
3000fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
3001fc903b3dSAndrew Geissler                                          std::string_view resetType,
3002fc903b3dSAndrew Geissler                                          crow::Response& res)
3003fc903b3dSAndrew Geissler {
3004fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
3005fc903b3dSAndrew Geissler     {
3006fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
3007fc903b3dSAndrew Geissler         return;
3008fc903b3dSAndrew Geissler     }
3009fc903b3dSAndrew Geissler 
3010fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
3011fc903b3dSAndrew Geissler     {
301262598e31SEd Tanous         BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
3013fc903b3dSAndrew Geissler         messages::internalError(res);
3014fc903b3dSAndrew Geissler         return;
3015fc903b3dSAndrew Geissler     }
3016fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
3017fc903b3dSAndrew Geissler 
3018fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
3019fc903b3dSAndrew Geissler     // user to retry in a bit
3020fc903b3dSAndrew Geissler     if ((errorMessage ==
3021fc903b3dSAndrew Geissler          std::string_view(
3022fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3023fc903b3dSAndrew Geissler         (errorMessage ==
3024fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3025fc903b3dSAndrew Geissler     {
302662598e31SEd Tanous         BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
3027fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
3028fc903b3dSAndrew Geissler         return;
3029fc903b3dSAndrew Geissler     }
3030fc903b3dSAndrew Geissler 
303162598e31SEd Tanous     BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
303262598e31SEd Tanous                      errorMessage);
3033fc903b3dSAndrew Geissler     messages::internalError(res);
3034fc903b3dSAndrew Geissler }
3035fc903b3dSAndrew Geissler 
3036c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
3037c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
30387f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3039c1e219d5SEd Tanous     const std::string& systemName)
3040c1e219d5SEd Tanous {
30413ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
304245ca1b86SEd Tanous     {
304345ca1b86SEd Tanous         return;
304445ca1b86SEd Tanous     }
3045c1e219d5SEd Tanous     if (systemName != "system")
3046c1e219d5SEd Tanous     {
3047c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3048c1e219d5SEd Tanous                                    systemName);
3049c1e219d5SEd Tanous         return;
3050c1e219d5SEd Tanous     }
30517f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
30527f3e84a1SEd Tanous     {
30537f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30547f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3055c1e219d5SEd Tanous                                    systemName);
30567f3e84a1SEd Tanous         return;
30577f3e84a1SEd Tanous     }
30589712f8acSEd Tanous     std::string resetType;
3059c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3060cc340dd9SEd Tanous     {
3061cc340dd9SEd Tanous         return;
3062cc340dd9SEd Tanous     }
3063cc340dd9SEd Tanous 
3064d22c8396SJason M. Bills     // Get the command and host vs. chassis
3065cc340dd9SEd Tanous     std::string command;
3066543f4400SEd Tanous     bool hostCommand = true;
3067d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
3068cc340dd9SEd Tanous     {
3069cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
3070d22c8396SJason M. Bills         hostCommand = true;
3071d22c8396SJason M. Bills     }
3072d22c8396SJason M. Bills     else if (resetType == "ForceOff")
3073d22c8396SJason M. Bills     {
3074d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3075d22c8396SJason M. Bills         hostCommand = false;
3076d22c8396SJason M. Bills     }
3077d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
3078d22c8396SJason M. Bills     {
3079c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
308086a0851aSJason M. Bills         hostCommand = true;
3081cc340dd9SEd Tanous     }
30829712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
3083cc340dd9SEd Tanous     {
3084cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
3085d22c8396SJason M. Bills         hostCommand = true;
3086cc340dd9SEd Tanous     }
30879712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3088cc340dd9SEd Tanous     {
30890fda0f12SGeorge Liu         command =
30900fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3091d22c8396SJason M. Bills         hostCommand = true;
3092d22c8396SJason M. Bills     }
3093d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3094d22c8396SJason M. Bills     {
309586a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
309686a0851aSJason M. Bills         hostCommand = true;
3097cc340dd9SEd Tanous     }
3098bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3099bfd5b826SLakshminarayana R. Kammath     {
3100bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3101bfd5b826SLakshminarayana R. Kammath         return;
3102bfd5b826SLakshminarayana R. Kammath     }
3103cc340dd9SEd Tanous     else
3104cc340dd9SEd Tanous     {
3105c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3106cc340dd9SEd Tanous         return;
3107cc340dd9SEd Tanous     }
3108cc340dd9SEd Tanous 
3109d22c8396SJason M. Bills     if (hostCommand)
3110d22c8396SJason M. Bills     {
31119ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31129ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
31139ae226faSGeorge Liu             "/xyz/openbmc_project/state/host0",
31149ae226faSGeorge Liu             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
31159ae226faSGeorge Liu             command,
3116fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3117fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3118cc340dd9SEd Tanous             if (ec)
3119cc340dd9SEd Tanous             {
3120fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3121fc903b3dSAndrew Geissler                                              asyncResp->res);
3122fc903b3dSAndrew Geissler 
3123cc340dd9SEd Tanous                 return;
3124cc340dd9SEd Tanous             }
3125f12894f8SJason M. Bills             messages::success(asyncResp->res);
31269ae226faSGeorge Liu         });
3127cc340dd9SEd Tanous     }
3128d22c8396SJason M. Bills     else
3129d22c8396SJason M. Bills     {
31309ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31319ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
31329ae226faSGeorge Liu             "/xyz/openbmc_project/state/chassis0",
31339ae226faSGeorge Liu             "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
31349ae226faSGeorge Liu             command,
3135fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3136fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3137d22c8396SJason M. Bills             if (ec)
3138d22c8396SJason M. Bills             {
3139fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3140fc903b3dSAndrew Geissler                                              asyncResp->res);
3141d22c8396SJason M. Bills                 return;
3142d22c8396SJason M. Bills             }
3143d22c8396SJason M. Bills             messages::success(asyncResp->res);
31449ae226faSGeorge Liu         });
3145d22c8396SJason M. Bills     }
3146d22c8396SJason M. Bills }
3147cc340dd9SEd Tanous 
3148c1e219d5SEd Tanous inline void handleComputerSystemHead(
3149dd60b9edSEd Tanous     App& app, const crow::Request& req,
31507f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31517f3e84a1SEd Tanous     const std::string& /*systemName*/)
3152dd60b9edSEd Tanous {
3153dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3154dd60b9edSEd Tanous     {
3155dd60b9edSEd Tanous         return;
3156dd60b9edSEd Tanous     }
3157dd60b9edSEd Tanous 
3158dd60b9edSEd Tanous     asyncResp->res.addHeader(
3159dd60b9edSEd Tanous         boost::beast::http::field::link,
3160dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3161dd60b9edSEd Tanous }
3162dd60b9edSEd Tanous 
31635c3e9272SAbhishek Patel inline void afterPortRequest(
31645c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31655c3e9272SAbhishek Patel     const boost::system::error_code& ec,
31665c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
31675c3e9272SAbhishek Patel {
31685c3e9272SAbhishek Patel     if (ec)
31695c3e9272SAbhishek Patel     {
3170b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
31715c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
31725c3e9272SAbhishek Patel         return;
31735c3e9272SAbhishek Patel     }
31745c3e9272SAbhishek Patel     for (const auto& data : socketData)
31755c3e9272SAbhishek Patel     {
31765c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
31775c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
31785c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
31795c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
31805c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
31815c3e9272SAbhishek Patel         // need to retrieve port number for
31825c3e9272SAbhishek Patel         // obmc-console-ssh service
31835c3e9272SAbhishek Patel         if (protocolName == "SSH")
31845c3e9272SAbhishek Patel         {
31855c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
318681c4e330SEd Tanous                                           const boost::system::error_code& ec1,
31875c3e9272SAbhishek Patel                                           int portNumber) {
31885c3e9272SAbhishek Patel                 if (ec1)
31895c3e9272SAbhishek Patel                 {
3190b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
31915c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
31925c3e9272SAbhishek Patel                     return;
31935c3e9272SAbhishek Patel                 }
31945c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
31955c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
31965c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
31975c3e9272SAbhishek Patel             });
31985c3e9272SAbhishek Patel         }
31995c3e9272SAbhishek Patel     }
32005c3e9272SAbhishek Patel }
3201c1e219d5SEd Tanous 
3202c1e219d5SEd Tanous inline void
3203c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
320422d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3205c1e219d5SEd Tanous                             const std::string& systemName)
3206c1e219d5SEd Tanous {
32073ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
320845ca1b86SEd Tanous     {
320945ca1b86SEd Tanous         return;
321045ca1b86SEd Tanous     }
3211746b56f3SAsmitha Karunanithi 
32127f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32137f3e84a1SEd Tanous     {
32147f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32157f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32167f3e84a1SEd Tanous                                    systemName);
32177f3e84a1SEd Tanous         return;
32187f3e84a1SEd Tanous     }
32197f3e84a1SEd Tanous 
3220746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3221746b56f3SAsmitha Karunanithi     {
3222746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3223746b56f3SAsmitha Karunanithi         return;
3224746b56f3SAsmitha Karunanithi     }
3225746b56f3SAsmitha Karunanithi 
322622d268cbSEd Tanous     if (systemName != "system")
322722d268cbSEd Tanous     {
322822d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
322922d268cbSEd Tanous                                    systemName);
323022d268cbSEd Tanous         return;
323122d268cbSEd Tanous     }
3232dd60b9edSEd Tanous     asyncResp->res.addHeader(
3233dd60b9edSEd Tanous         boost::beast::http::field::link,
3234dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
32358d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
323637bbf98cSChris Cain         "#ComputerSystem.v1_16_0.ComputerSystem";
32378d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
32388d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
32398d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
32408d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
32418d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
32425fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
32435fd0aafbSNinad Palsule     {
32448d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
32458d1b46d7Szhanghch05             "Disabled";
32468d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
32478d1b46d7Szhanghch05             "Disabled";
32485fd0aafbSNinad Palsule     }
3249cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3250dfb2b408SPriyanga Ramasamy         double(0);
3251002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
325204a258f4SEd Tanous 
32531476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
32541476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
32551476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
32561476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
32571476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
32581476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
32593179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
32603179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3261029573d4SEd Tanous 
3262002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
32631476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3264c1e219d5SEd Tanous     asyncResp->res
3265c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
32661476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3267c5b2abe0SLewanczyk, Dawid 
32681476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
32691476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
32701476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
32711476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3272c4bf6374SJason M. Bills 
32731476687dSEd Tanous     nlohmann::json::array_t managedBy;
32741476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
32751476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3276002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
32771476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
32781476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
32790e8ac5e7SGunnar Mills 
32800e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3281002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3282c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
32831476687dSEd Tanous 
3284c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
32851476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3286c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
32871476687dSEd Tanous         "Press ~. to exit console";
32885c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
32895c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
32900e8ac5e7SGunnar Mills 
32910e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
32920e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3293002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3294c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3295613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3296613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
32971476687dSEd Tanous 
32980e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
329913451e39SWilly Tu 
330013451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
330113451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
330213451e39SWilly Tu     {
33037a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3304b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
33052ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3306e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3307e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3308b49ac873SJames Feist 
33097a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
33107a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
33117a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3312914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3313b49ac873SJames Feist             if (ec)
3314b49ac873SJames Feist             {
3315b49ac873SJames Feist                 // no inventory
3316b49ac873SJames Feist                 return;
3317b49ac873SJames Feist             }
3318b49ac873SJames Feist 
3319914e2d5dSEd Tanous             health->inventory = resp;
33207a1dbc48SGeorge Liu         });
3321b49ac873SJames Feist         health->populate();
332213451e39SWilly Tu     }
3323b49ac873SJames Feist 
3324002d39b4SEd Tanous     getMainChassisId(asyncResp,
3325002d39b4SEd Tanous                      [](const std::string& chassisId,
33268d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3327b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3328b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3329ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3330ef4c65b7SEd Tanous                                                    chassisId);
3331002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3332c5d03ff4SJennifer Lee     });
3333a3002228SAppaRao Puli 
33349f8bfa7cSGunnar Mills     getLocationIndicatorActive(asyncResp);
33359f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3336a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
33375bc2dc8eSJames Feist     getComputerSystem(asyncResp, health);
33386c34de48SEd Tanous     getHostState(asyncResp);
3339491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3340978b8803SAndrew Geissler     getBootProgress(asyncResp);
3341b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
3342472bd202SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
334351709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3344c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
33459dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3346797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3347c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3348a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3349a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3350a6349918SAppaRao Puli #endif
33511981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
33523a2d0424SChris Cain     getPowerMode(asyncResp);
335337bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3354c1e219d5SEd Tanous }
3355550a6bf8SJiaqing Zhao 
3356c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3357c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
335822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3359c1e219d5SEd Tanous     const std::string& systemName)
3360c1e219d5SEd Tanous {
33613ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
336245ca1b86SEd Tanous     {
336345ca1b86SEd Tanous         return;
336445ca1b86SEd Tanous     }
33657f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
33667f3e84a1SEd Tanous     {
33677f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
33687f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
33697f3e84a1SEd Tanous                                    systemName);
33707f3e84a1SEd Tanous         return;
33717f3e84a1SEd Tanous     }
337222d268cbSEd Tanous     if (systemName != "system")
337322d268cbSEd Tanous     {
337422d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
337522d268cbSEd Tanous                                    systemName);
337622d268cbSEd Tanous         return;
337722d268cbSEd Tanous     }
337822d268cbSEd Tanous 
3379dd60b9edSEd Tanous     asyncResp->res.addHeader(
3380dd60b9edSEd Tanous         boost::beast::http::field::link,
3381dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3382dd60b9edSEd Tanous 
33839f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3384cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
338598e386ecSGunnar Mills     std::optional<std::string> assetTag;
3386c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
33873a2d0424SChris Cain     std::optional<std::string> powerMode;
3388550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3389550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3390550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3391550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3392550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3393550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3394797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3395550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
33969dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3397550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3398550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3399550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3400550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3401550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3402550a6bf8SJiaqing Zhao 
3403550a6bf8SJiaqing Zhao     // clang-format off
340415ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3405550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3406550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
34077e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3408550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3409550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3410550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3411550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3412550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3413550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3414550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3415550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3416550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3417797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3418550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
34199dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3420550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3421550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3422550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3423550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3424550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
34256617338dSEd Tanous                 {
34266617338dSEd Tanous                     return;
34276617338dSEd Tanous                 }
3428550a6bf8SJiaqing Zhao     // clang-format on
3429491d8ee7SSantosh Puranik 
34308d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3431c45f0082SYong Li 
343298e386ecSGunnar Mills     if (assetTag)
343398e386ecSGunnar Mills     {
343498e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
343598e386ecSGunnar Mills     }
343698e386ecSGunnar Mills 
3437550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3438c45f0082SYong Li     {
3439f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3440c45f0082SYong Li     }
3441c45f0082SYong Li 
3442cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
344369f35306SGunnar Mills     {
3444002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3445491d8ee7SSantosh Puranik     }
3446550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
344769f35306SGunnar Mills     {
3448550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
344969f35306SGunnar Mills     }
3450ac7e1e0bSAli Ahmed 
3451797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3452797d5daeSCorey Hardesty     {
3453797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3454797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3455797d5daeSCorey Hardesty     }
3456797d5daeSCorey Hardesty 
3457550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3458ac7e1e0bSAli Ahmed     {
3459c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
346069f35306SGunnar Mills     }
3461265c1602SJohnathan Mantey 
34629dcfe8c1SAlbert Zhang     if (stopBootOnFault)
34639dcfe8c1SAlbert Zhang     {
34649dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
34659dcfe8c1SAlbert Zhang     }
34669dcfe8c1SAlbert Zhang 
34679f8bfa7cSGunnar Mills     if (locationIndicatorActive)
34689f8bfa7cSGunnar Mills     {
3469002d39b4SEd Tanous         setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
34709f8bfa7cSGunnar Mills     }
34719f8bfa7cSGunnar Mills 
34727e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
34737e860f15SJohn Edward Broadbent     // passed
34749712f8acSEd Tanous     if (indicatorLed)
34756617338dSEd Tanous     {
3476f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3477002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3478d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3479d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
34806617338dSEd Tanous     }
3481c6a620f2SGeorge Liu 
3482c6a620f2SGeorge Liu     if (powerRestorePolicy)
3483c6a620f2SGeorge Liu     {
34844e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3485c6a620f2SGeorge Liu     }
34863a2d0424SChris Cain 
34873a2d0424SChris Cain     if (powerMode)
34883a2d0424SChris Cain     {
34893a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
34903a2d0424SChris Cain     }
349137bbf98cSChris Cain 
3492c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
349337bbf98cSChris Cain     {
3494002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3495002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
349637bbf98cSChris Cain     }
3497c1e219d5SEd Tanous }
34981cb1a9e6SAppaRao Puli 
349938c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3500dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
35017f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3502c1e219d5SEd Tanous     const std::string& /*systemName*/)
3503dd60b9edSEd Tanous {
3504dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3505dd60b9edSEd Tanous     {
3506dd60b9edSEd Tanous         return;
3507dd60b9edSEd Tanous     }
3508dd60b9edSEd Tanous     asyncResp->res.addHeader(
3509dd60b9edSEd Tanous         boost::beast::http::field::link,
3510dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3511dd60b9edSEd Tanous }
3512c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3513c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
351422d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3515c1e219d5SEd Tanous     const std::string& systemName)
3516c1e219d5SEd Tanous {
35173ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
351845ca1b86SEd Tanous     {
351945ca1b86SEd Tanous         return;
352045ca1b86SEd Tanous     }
35217f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
35227f3e84a1SEd Tanous     {
35237f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
35247f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
35257f3e84a1SEd Tanous                                    systemName);
35267f3e84a1SEd Tanous         return;
35277f3e84a1SEd Tanous     }
3528746b56f3SAsmitha Karunanithi 
3529746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3530746b56f3SAsmitha Karunanithi     {
3531746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3532746b56f3SAsmitha Karunanithi         return;
3533746b56f3SAsmitha Karunanithi     }
3534746b56f3SAsmitha Karunanithi 
353522d268cbSEd Tanous     if (systemName != "system")
353622d268cbSEd Tanous     {
353722d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
353822d268cbSEd Tanous                                    systemName);
353922d268cbSEd Tanous         return;
354022d268cbSEd Tanous     }
354122d268cbSEd Tanous 
3542dd60b9edSEd Tanous     asyncResp->res.addHeader(
3543dd60b9edSEd Tanous         boost::beast::http::field::link,
3544dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
35451476687dSEd Tanous 
35461476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
35471476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3548c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
35491476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
35501476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
35513215e700SNan Zhou 
35523215e700SNan Zhou     nlohmann::json::array_t parameters;
35533215e700SNan Zhou     nlohmann::json::object_t parameter;
35543215e700SNan Zhou 
35553215e700SNan Zhou     parameter["Name"] = "ResetType";
35563215e700SNan Zhou     parameter["Required"] = true;
35573215e700SNan Zhou     parameter["DataType"] = "String";
35583215e700SNan Zhou     nlohmann::json::array_t allowableValues;
35593215e700SNan Zhou     allowableValues.emplace_back("On");
35603215e700SNan Zhou     allowableValues.emplace_back("ForceOff");
35613215e700SNan Zhou     allowableValues.emplace_back("ForceOn");
35623215e700SNan Zhou     allowableValues.emplace_back("ForceRestart");
35633215e700SNan Zhou     allowableValues.emplace_back("GracefulRestart");
35643215e700SNan Zhou     allowableValues.emplace_back("GracefulShutdown");
35653215e700SNan Zhou     allowableValues.emplace_back("PowerCycle");
35663215e700SNan Zhou     allowableValues.emplace_back("Nmi");
35673215e700SNan Zhou     parameter["AllowableValues"] = std::move(allowableValues);
35683215e700SNan Zhou     parameters.emplace_back(std::move(parameter));
35693215e700SNan Zhou 
35703215e700SNan Zhou     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3571c1e219d5SEd Tanous }
3572c1e219d5SEd Tanous /**
3573c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3574c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3575c1e219d5SEd Tanous  */
3576100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3577c1e219d5SEd Tanous {
3578100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3579100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3580100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3581100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3582100afe56SEd Tanous 
3583100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3584100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3585100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3586100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3587100afe56SEd Tanous 
3588100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3589100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3590100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3591100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3592100afe56SEd Tanous 
3593100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3594100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3595100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3596100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3597100afe56SEd Tanous 
3598100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3599100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3600100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3601100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3602100afe56SEd Tanous 
3603100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3604100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3605100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3606100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3607100afe56SEd Tanous 
3608c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3609c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3610c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3611c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3612c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3613c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3614c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3615c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36161cb1a9e6SAppaRao Puli }
3617c5b2abe0SLewanczyk, Dawid } // namespace redfish
3618